@@ -152,6 +152,7 @@ AC_HAVE_DEVMAPPER
AC_HAVE_MALLINFO
AC_HAVE_MALLINFO2
AC_HAVE_MEMFD_CREATE
+AC_HAVE_GETRANDOM_NONBLOCK
if test "$enable_scrub" = "yes"; then
if test "$enable_libicu" = "yes" || test "$enable_libicu" = "probe"; then
AC_HAVE_LIBICU
@@ -102,6 +102,7 @@ HAVE_DEVMAPPER = @have_devmapper@
HAVE_MALLINFO = @have_mallinfo@
HAVE_MALLINFO2 = @have_mallinfo2@
HAVE_MEMFD_CREATE = @have_memfd_create@
+HAVE_GETRANDOM_NONBLOCK = @have_getrandom_nonblock@
HAVE_LIBICU = @have_libicu@
HAVE_SYSTEMD = @have_systemd@
SYSTEMD_SYSTEM_UNIT_DIR = @systemd_system_unit_dir@
@@ -135,6 +135,10 @@ ifeq ($(HAVE_MEMFD_CREATE),yes)
LCFLAGS += -DHAVE_MEMFD_CREATE
endif
+ifeq ($(HAVE_GETRANDOM_NONBLOCK),yes)
+LCFLAGS += -DHAVE_GETRANDOM_NONBLOCK
+endif
+
FCFLAGS = -I.
LTLIBS = $(LIBPTHREAD) $(LIBRT)
@@ -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()
@@ -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
@@ -195,6 +195,21 @@ memfd_create(0, 0);
AC_SUBST(have_memfd_create)
])
+#
+# 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"
@@ -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);