]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_io: try to unshare copy-on-write blocks via fallocate
authorDarrick J. Wong <darrick.wong@oracle.com>
Tue, 25 Oct 2016 22:14:33 +0000 (15:14 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 26 Oct 2016 19:43:53 +0000 (12:43 -0700)
Wire up the "unshare" flag to the xfs_io fallocate command.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
io/prealloc.c
man/man8/xfs_io.8

index 7f5c200261ab949d0df605789003056dfd8a570e..a9d66cce05c6c8df310fe1ce1185f40522a4af60 100644 (file)
 #define FALLOC_FL_INSERT_RANGE 0x20
 #endif
 
+#ifndef FALLOC_FL_UNSHARE_RANGE
+#define FALLOC_FL_UNSHARE_RANGE 0x40
+#endif
+
 static cmdinfo_t allocsp_cmd;
 static cmdinfo_t freesp_cmd;
 static cmdinfo_t resvsp_cmd;
@@ -181,6 +185,7 @@ falloc_help(void)
 " -i -- inserts a hole into the given range of the file.\n"
 " -k -- do not change file size.\n"
 " -p -- unmap the given range from the file.\n"
+" -u -- unshare shared extents in the given range.\n"
 "\n"));
 }
 
@@ -193,7 +198,7 @@ fallocate_f(
        int             mode = 0;
        int             c;
 
-       while ((c = getopt(argc, argv, "cikp")) != EOF) {
+       while ((c = getopt(argc, argv, "cikpu")) != EOF) {
                switch (c) {
                case 'c':
                        mode = FALLOC_FL_COLLAPSE_RANGE;
@@ -207,6 +212,9 @@ fallocate_f(
                case 'p':
                        mode = FALLOC_FL_PUNCH_HOLE;
                        break;
+               case 'u':
+                       mode = FALLOC_FL_UNSHARE_RANGE;
+                       break;
                default:
                        command_usage(&falloc_cmd);
                }
@@ -306,6 +314,26 @@ fzero_f(
        }
        return 0;
 }
+
+static int
+funshare_f(
+       int             argc,
+       char            **argv)
+{
+       xfs_flock64_t   segment;
+       int             mode = FALLOC_FL_UNSHARE_RANGE;
+       int             index = 1;
+
+       if (!offset_length(argv[index], argv[index + 1], &segment))
+               return 0;
+
+       if (fallocate(file->fd, mode,
+                       segment.l_start, segment.l_len)) {
+               perror("fallocate");
+               return 0;
+       }
+       return 0;
+}
 #endif /* HAVE_FALLOCATE */
 
 void
@@ -366,7 +394,7 @@ prealloc_init(void)
        falloc_cmd.argmin = 2;
        falloc_cmd.argmax = -1;
        falloc_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
-       falloc_cmd.args = _("[-c] [-k] [-p] off len");
+       falloc_cmd.args = _("[-c] [-k] [-p] [-u] off len");
        falloc_cmd.oneline =
        _("allocates space associated with part of a file via fallocate");
        falloc_cmd.help = falloc_help;
@@ -411,5 +439,15 @@ prealloc_init(void)
        fzero_cmd.oneline =
        _("zeroes space and eliminates holes by preallocating");
        add_command(&fzero_cmd);
+
+       fzero_cmd.name = "funshare";
+       fzero_cmd.cfunc = funshare_f;
+       fzero_cmd.argmin = 2;
+       fzero_cmd.argmax = 2;
+       fzero_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
+       fzero_cmd.args = _("off len");
+       fzero_cmd.oneline =
+       _("unshares shared blocks within the range");
+       add_command(&fzero_cmd);
 #endif /* HAVE_FALLOCATE */
 }
index 2365550b31d907ec269dab360ee1deafac1ea90a..eb7b878d88f8fd37e7fd196d4bdf33b0c63c44b4 100644 (file)
@@ -431,6 +431,11 @@ the FALLOC_FL_PUNCH_HOLE flag as described in the
 .BR fallocate (2)
 manual page.
 .TP
+.BI funshare " offset length"
+Call fallocate with FALLOC_FL_UNSHARE_RANGE flag as described in the
+.BR fallocate (2)
+manual page to unshare all shared blocks within the range.
+.TP
 .BI fzero " offset length"
 Call fallocate with FALLOC_FL_ZERO_RANGE flag as described in the
 .BR fallocate (2)