]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
mkfs: Break block discard into chunks of 2 GB
authorPavel Reichl <preichl@redhat.com>
Fri, 13 Dec 2019 21:21:26 +0000 (16:21 -0500)
committerEric Sandeen <sandeen@redhat.com>
Fri, 13 Dec 2019 21:21:26 +0000 (16:21 -0500)
Some users are not happy about the BLKDISCARD taking too long and at the
same time not being informed about that - so they think that the command
actually hung.

This commit changes code so that progress reporting is possible and also
typing the ^C will cancel the ongoing BLKDISCARD.

Signed-off-by: Pavel Reichl <preichl@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
mkfs/xfs_mkfs.c

index 18338a61476913a443f1f43f025a484925ce0e49..4bfdebf6f396202a388f8a96d2598a866aedeadd 100644 (file)
@@ -1240,17 +1240,40 @@ done:
 }
 
 static void
-discard_blocks(dev_t dev, uint64_t nsectors)
+discard_blocks(dev_t dev, uint64_t nsectors, int quiet)
 {
-       int fd;
+       int             fd;
+       uint64_t        offset = 0;
+       /* Discard the device 2G at a time */
+       const uint64_t  step = 2ULL << 30;
+       const uint64_t  count = BBTOB(nsectors);
 
-       /*
-        * We intentionally ignore errors from the discard ioctl.  It is
-        * not necessary for the mkfs functionality but just an optimization.
-        */
        fd = libxfs_device_to_fd(dev);
-       if (fd > 0)
-               platform_discard_blocks(fd, 0, nsectors << 9);
+       if (fd <= 0)
+               return;
+       if (!quiet) {
+               printf("Discarding blocks...");
+               fflush(stdout);
+       }
+
+       /* The block discarding happens in smaller batches so it can be
+        * interrupted prematurely
+        */
+       while (offset < count) {
+               uint64_t        tmp_step = min(step, count - offset);
+
+               /*
+                * We intentionally ignore errors from the discard ioctl. It is
+                * not necessary for the mkfs functionality but just an
+                * optimization. However we should stop on error.
+                */
+               if (platform_discard_blocks(fd, offset, tmp_step))
+                       return;
+
+               offset += tmp_step;
+       }
+       if (!quiet)
+               printf("Done.\n");
 }
 
 static __attribute__((noreturn)) void
@@ -2507,18 +2530,19 @@ open_devices(
 
 static void
 discard_devices(
-       struct libxfs_xinit     *xi)
+       struct libxfs_xinit     *xi,
+       int                     quiet)
 {
        /*
         * This function has to be called after libxfs has been initialized.
         */
 
        if (!xi->disfile)
-               discard_blocks(xi->ddev, xi->dsize);
+               discard_blocks(xi->ddev, xi->dsize, quiet);
        if (xi->rtdev && !xi->risfile)
-               discard_blocks(xi->rtdev, xi->rtsize);
+               discard_blocks(xi->rtdev, xi->rtsize, quiet);
        if (xi->logdev && xi->logdev != xi->ddev && !xi->lisfile)
-               discard_blocks(xi->logdev, xi->logBBsize);
+               discard_blocks(xi->logdev, xi->logBBsize, quiet);
 }
 
 static void
@@ -3749,7 +3773,7 @@ main(
         * All values have been validated, discard the old device layout.
         */
        if (discard && !dry_run)
-               discard_devices(&xi);
+               discard_devices(&xi, quiet);
 
        /*
         * we need the libxfs buffer cache from here on in.