]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
libxfs: use FALLOC_FL_ZERO_RANGE in libxfs_device_zero
authorEric Sandeen <sandeen@redhat.com>
Thu, 27 Feb 2020 20:05:48 +0000 (15:05 -0500)
committerEric Sandeen <sandeen@sandeen.net>
Thu, 27 Feb 2020 20:05:48 +0000 (15:05 -0500)
I had a request from someone who cared about mkfs speed over
a slower network block device to look into using faster zeroing
methods, particularly for the log, during mkfs.

Using FALLOC_FL_ZERO_RANGE is faster in this case than writing
a bunch of zeros across a wire.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
include/builddefs.in
include/linux.h
libxfs/rdwr.c

index 4700b52706a76cda54a91185b8eb63c6c71cd08a..1dd27f760306dc78ed6461df5aaa07d385ff8806 100644 (file)
@@ -144,6 +144,9 @@ endif
 ifeq ($(HAVE_GETFSMAP),yes)
 PCFLAGS+= -DHAVE_GETFSMAP
 endif
+ifeq ($(HAVE_FALLOCATE),yes)
+PCFLAGS += -DHAVE_FALLOCATE
+endif
 
 LIBICU_LIBS = @libicu_LIBS@
 LIBICU_CFLAGS = @libicu_CFLAGS@
index 8f3c32b0d36e5c294cf188fabad7080b18d38908..57726bb12b7416e794db1602ebdbda982734c14a 100644 (file)
 #include <stdio.h>
 #include <asm/types.h>
 #include <mntent.h>
+#include <fcntl.h>
+#if defined(HAVE_FALLOCATE)
+#include <linux/falloc.h>
+#endif
 #ifdef OVERRIDE_SYSTEM_FSXATTR
 # define fsxattr sys_fsxattr
 #endif
@@ -164,6 +168,24 @@ static inline void platform_mntent_close(struct mntent_cursor * cursor)
        endmntent(cursor->mtabp);
 }
 
+#if defined(FALLOC_FL_ZERO_RANGE)
+static inline int
+platform_zero_range(
+       int             fd,
+       xfs_off_t       start,
+       size_t          len)
+{
+       int ret;
+
+       ret = fallocate(fd, FALLOC_FL_ZERO_RANGE, start, len);
+       if (!ret)
+               return 0;
+       return -errno;
+}
+#else
+#define platform_zero_range(fd, s, l)  (-EOPNOTSUPP)
+#endif
+
 /*
  * Check whether we have to define FS_IOC_FS[GS]ETXATTR ourselves. These
  * are a copy of the definitions moved to linux/uapi/fs.h in the 4.5 kernel,
index 0d9d72022ec3660720af0ac6cfa7885fb8b7df86..e2d9d790452a65e35f406c602dbd271bc8f282dd 100644 (file)
@@ -61,8 +61,18 @@ libxfs_device_zero(struct xfs_buftarg *btp, xfs_daddr_t start, uint len)
 {
        xfs_off_t       start_offset, end_offset, offset;
        ssize_t         zsize, bytes;
+       size_t          len_bytes;
        char            *z;
-       int             fd;
+       int             error, fd;
+
+       fd = libxfs_device_to_fd(btp->dev);
+       start_offset = LIBXFS_BBTOOFF64(start);
+
+       /* try to use special zeroing methods, fall back to writes if needed */
+       len_bytes = LIBXFS_BBTOOFF64(len);
+       error = platform_zero_range(fd, start_offset, len_bytes);
+       if (!error)
+               return 0;
 
        zsize = min(BDSTRAT_SIZE, BBTOB(len));
        if ((z = memalign(libxfs_device_alignment(), zsize)) == NULL) {
@@ -73,9 +83,6 @@ libxfs_device_zero(struct xfs_buftarg *btp, xfs_daddr_t start, uint len)
        }
        memset(z, 0, zsize);
 
-       fd = libxfs_device_to_fd(btp->dev);
-       start_offset = LIBXFS_BBTOOFF64(start);
-
        if ((lseek(fd, start_offset, SEEK_SET)) < 0) {
                fprintf(stderr, _("%s: %s seek to offset %llu failed: %s\n"),
                        progname, __FUNCTION__,