]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
libxfs: implement get_random_u32
authorDarrick J. Wong <djwong@kernel.org>
Wed, 3 Jul 2024 21:21:34 +0000 (14:21 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 31 Jul 2024 01:46:42 +0000 (18:46 -0700)
Actually query the kernel for some random bytes instead of returning
zero, if that's possible.  The most noticeable effect of this is that
mkfs will now create the rtbitmap file, the rtsummary file, and children
of the root directory with a nonzero generation.  Apparently xfsdump
requires that the root directory have a generation number of zero.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
configure.ac
include/builddefs.in
libxfs/Makefile
libxfs/libxfs_priv.h
libxfs/util.c
m4/package_libcdev.m4
mkfs/proto.c

index b84234b50e0eb8cae3aac04e08fab8a1ccdec9c3..e2fb13165970ee1b7c620d26ef0b8af4107cda14 100644 (file)
@@ -151,6 +151,7 @@ AC_HAVE_MAP_SYNC
 AC_HAVE_DEVMAPPER
 AC_HAVE_MALLINFO
 AC_HAVE_MALLINFO2
+AC_HAVE_GETRANDOM_NONBLOCK
 AC_PACKAGE_WANT_ATTRIBUTES_H
 AC_HAVE_LIBATTR
 if test "$enable_scrub" = "yes"; then
index 734bd95ecb0b339e9d0ccf3409978912fdf8f870..193b9c19dfe890276cb0b2f4f7f0f2fcb8d55160 100644 (file)
@@ -101,6 +101,7 @@ HAVE_MAP_SYNC = @have_map_sync@
 HAVE_DEVMAPPER = @have_devmapper@
 HAVE_MALLINFO = @have_mallinfo@
 HAVE_MALLINFO2 = @have_mallinfo2@
+HAVE_GETRANDOM_NONBLOCK = @have_getrandom_nonblock@
 HAVE_LIBATTR = @have_libattr@
 HAVE_LIBICU = @have_libicu@
 HAVE_SYSTEMD = @have_systemd@
index 3d0ac2987f6e1abcaca3a5db8fc8221f608f9434..65a7934fbcaf2c1d858e98725ec0fed0eaaf23d5 100644 (file)
@@ -131,6 +131,10 @@ CFILES = buf_mem.c \
 #
 #LCFLAGS +=
 
+ifeq ($(HAVE_GETRANDOM_NONBLOCK),yes)
+       LCFLAGS += -DHAVE_GETRANDOM_NONBLOCK
+endif
+
 FCFLAGS = -I.
 
 LTLIBS = $(LIBPTHREAD) $(LIBRT)
index ecacfff82d722b948e39459383f5fb5d535ed777..8dd364b0da914ad36a91a0df5fb29b7cf04729ac 100644 (file)
@@ -63,6 +63,9 @@
 #include "libfrog/crc32c.h"
 
 #include <sys/xattr.h>
+#ifdef HAVE_GETRANDOM_NONBLOCK
+#include <sys/random.h>
+#endif
 
 /* Zones used in libxfs allocations that aren't in shared header files */
 extern struct kmem_cache *xfs_buf_item_cache;
@@ -212,11 +215,11 @@ static inline bool WARN_ON(bool expr) {
 #define percpu_counter_read_positive(x)        ((*x) > 0 ? (*x) : 0)
 #define percpu_counter_sum_positive(x) ((*x) > 0 ? (*x) : 0)
 
-/*
- * get_random_u32 is used for di_gen inode allocation, it must be zero for
- * libxfs or all sorts of badness can occur!
- */
+#ifdef HAVE_GETRANDOM_NONBLOCK
+uint32_t get_random_u32(void);
+#else
 #define get_random_u32()       (0)
+#endif
 
 #define PAGE_SIZE              getpagesize()
 
index 7aa92c0e4a66a9c2cc2bd56e6e71cd98cf7dbac9..a3f3ad299336c7c57d427ea41c7058e91777da60 100644 (file)
@@ -462,3 +462,22 @@ void xfs_dirattr_mark_sick(struct xfs_inode *ip, int whichfork) { }
 void xfs_da_mark_sick(struct xfs_da_args *args) { }
 void xfs_inode_mark_sick(struct xfs_inode *ip, unsigned int mask) { }
 void xfs_rt_mark_sick(struct xfs_mount *mp, unsigned int mask) { }
+
+#ifdef HAVE_GETRANDOM_NONBLOCK
+uint32_t
+get_random_u32(void)
+{
+       uint32_t        ret;
+       ssize_t         sz;
+
+       /*
+        * Try to extract a u32 of randomness from /dev/urandom.  If that
+        * fails, fall back to returning zero like we used to do.
+        */
+       sz = getrandom(&ret, sizeof(ret), GRND_NONBLOCK);
+       if (sz != sizeof(ret))
+               return 0;
+
+       return ret;
+}
+#endif
index de64c9af7fdef2d50fd3fd27f3d4b8c34f0c0803..31fcf4d7aa79b1875134ed5c0124e61415fbe79e 100644 (file)
@@ -177,6 +177,21 @@ test = mallinfo2();
     AC_SUBST(have_mallinfo2)
   ])
 
+#
+# Check if we have a getrandom syscall with a GRND_NONBLOCK flag
+#
+AC_DEFUN([AC_HAVE_GETRANDOM_NONBLOCK],
+  [ AC_MSG_CHECKING([for getrandom and GRND_NONBLOCK])
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/random.h>
+    ]], [[
+         unsigned int moo;
+         return getrandom(&moo, sizeof(moo), GRND_NONBLOCK);
+    ]])],[have_getrandom_nonblock=yes
+       AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)])
+    AC_SUBST(have_getrandom_nonblock)
+  ])
+
 AC_DEFUN([AC_PACKAGE_CHECK_LTO],
   [ AC_MSG_CHECKING([if C compiler supports LTO])
     OLD_CFLAGS="$CFLAGS"
index 58edc59f7152cdff00a0959991dfd72a877e9dd2..96cb9f8544bf853adf5228cc736992750fcf1c34 100644 (file)
@@ -462,6 +462,9 @@ creatproto(
                                                        fsx->fsx_xflags);
                        ip->i_cowextsize = fsx->fsx_cowextsize;
                }
+
+               /* xfsdump breaks if the root dir has a nonzero generation */
+               inode->i_generation = 0;
        }
 
        libxfs_trans_log_inode(*tpp, ip, XFS_ILOG_CORE);