]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
io: update reflink/dedupe ioctl definitions
authorDarrick J. Wong <darrick.wong@oracle.com>
Tue, 10 Nov 2015 00:20:09 +0000 (11:20 +1100)
committerDave Chinner <david@fromorbit.com>
Tue, 10 Nov 2015 00:20:09 +0000 (11:20 +1100)
The committed version was a pre-review version of the ioctl
interface. Update it to match post-review
version.

[dchinner: I've just aplied the latest patches over the top of
 what I originally committed, so the diff here isn't exactly what
 Darrick originally sent. ]

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
io/Makefile
io/dedupe.c [deleted file]
io/init.c
io/io.h
io/reflink.c
libxfs/xfs_fs.h
man/man8/xfs_io.8

index a5f2ac929a22224f89b3b17808816d38b7f21da0..0b53f4187ba9eee4fc34cc2462fac3f89a78f4dc 100644 (file)
@@ -11,7 +11,7 @@ HFILES = init.h io.h
 CFILES = init.c \
        attr.c bmap.c file.c freeze.c fsync.c getrusage.c imap.c link.c \
        mmap.c open.c parent.c pread.c prealloc.c pwrite.c seek.c shutdown.c \
-       sync.c truncate.c reflink.c dedupe.c
+       sync.c truncate.c reflink.c
 
 LLDLIBS = $(LIBXCMD) $(LIBHANDLE)
 LTDEPENDENCIES = $(LIBXCMD) $(LIBHANDLE)
diff --git a/io/dedupe.c b/io/dedupe.c
deleted file mode 100644 (file)
index 59c3d0f..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2015 Oracle, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <sys/uio.h>
-#include <xfs/xfs.h>
-#include "command.h"
-#include "input.h"
-#include "init.h"
-#include "io.h"
-
-static cmdinfo_t dedupe_cmd;
-
-static void
-dedupe_help(void)
-{
-       printf(_(
-"\n"
-" Links a range of bytes (in block size increments) from a file into a range \n"
-" of bytes in the open file.  The contents of both file ranges must match.\n"
-"\n"
-" Example:\n"
-" 'dedupe some_file 0 4096 32768' - links 32768 bytes from some_file at \n"
-"                                    offset 0 to into the open file at \n"
-"                                    position 4096\n"
-"\n"
-" Reflink a range of blocks from a given input file to the open file.  Both\n"
-" files share the same range of physical disk blocks; a write to the shared\n"
-" range of either file should result in the write landing in a new block and\n"
-" that range of the file being remapped (i.e. copy-on-write).  Both files\n"
-" must reside on the same filesystem, and the contents of both ranges must\n"
-" match.\n"
-" -w   -- call fdatasync(2) at the end (included in timing results)\n"
-" -W   -- call fsync(2) at the end (included in timing results)\n"
-"\n"));
-}
-
-static int
-dedupe_f(
-       int             argc,
-       char            **argv)
-{
-       off64_t         soffset, doffset;
-       long long       count, total;
-       char            s1[64], s2[64], ts[64];
-       char            *infile;
-       int             Cflag, qflag, wflag, Wflag;
-       struct xfs_ioctl_file_extent_same_args  *args = NULL;
-       struct xfs_ioctl_file_extent_same_info  *info;
-       size_t          fsblocksize, fssectsize;
-       struct timeval  t1, t2;
-       int             c, fd = -1;
-
-       Cflag = qflag = wflag = Wflag = 0;
-       init_cvtnum(&fsblocksize, &fssectsize);
-
-       while ((c = getopt(argc, argv, "CqwW")) != EOF) {
-               switch (c) {
-               case 'C':
-                       Cflag = 1;
-                       break;
-               case 'q':
-                       qflag = 1;
-                       break;
-               case 'w':
-                       wflag = 1;
-                       break;
-               case 'W':
-                       Wflag = 1;
-                       break;
-               default:
-                       return command_usage(&dedupe_cmd);
-               }
-       }
-       if (optind != argc - 4)
-               return command_usage(&dedupe_cmd);
-       infile = argv[optind];
-       optind++;
-       soffset = cvtnum(fsblocksize, fssectsize, argv[optind]);
-       if (soffset < 0) {
-               printf(_("non-numeric src offset argument -- %s\n"), argv[optind]);
-               return 0;
-       }
-       optind++;
-       doffset = cvtnum(fsblocksize, fssectsize, argv[optind]);
-       if (doffset < 0) {
-               printf(_("non-numeric dest offset argument -- %s\n"), argv[optind]);
-               return 0;
-       }
-       optind++;
-       count = cvtnum(fsblocksize, fssectsize, argv[optind]);
-       if (count < 1) {
-               printf(_("non-positive length argument -- %s\n"), argv[optind]);
-               return 0;
-       }
-
-       c = IO_READONLY;
-       fd = openfile(infile, NULL, c, 0);
-       if (fd < 0)
-               return 0;
-
-       gettimeofday(&t1, NULL);
-       args = calloc(1, sizeof(struct xfs_ioctl_file_extent_same_args) +
-                        sizeof(struct xfs_ioctl_file_extent_same_info));
-       if (!args)
-               goto done;
-       info = (struct xfs_ioctl_file_extent_same_info *)(args + 1);
-       args->logical_offset = soffset;
-       args->length = count;
-       args->dest_count = 1;
-       info->fd = file->fd;
-       info->logical_offset = doffset;
-       do {
-               c = ioctl(fd, XFS_IOC_FILE_EXTENT_SAME, args);
-               if (c)
-                       break;
-               args->logical_offset += info->bytes_deduped;
-               info->logical_offset += info->bytes_deduped;
-               args->length -= info->bytes_deduped;
-       } while (c == 0 && info->status == 0 && info->bytes_deduped > 0);
-       if (c)
-               perror(_("dedupe ioctl"));
-       if (info->status < 0)
-               printf("dedupe: %s\n", _(strerror(-info->status)));
-       if (info->status == XFS_SAME_DATA_DIFFERS)
-               printf(_("Extents did not match.\n"));
-       if (c != 0 || info->status != 0)
-               goto done;
-       total = info->bytes_deduped;
-       c = 1;
-       if (Wflag)
-               fsync(file->fd);
-       if (wflag)
-               fdatasync(file->fd);
-       if (qflag)
-               goto done;
-       gettimeofday(&t2, NULL);
-       t2 = tsub(t2, t1);
-
-       /* Finally, report back -- -C gives a parsable format */
-       timestr(&t2, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0);
-       if (!Cflag) {
-               cvtstr((double)total, s1, sizeof(s1));
-               cvtstr(tdiv((double)total, t2), s2, sizeof(s2));
-               printf(_("linked %lld/%lld bytes at offset %lld\n"),
-                       total, count, (long long)doffset);
-               printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"),
-                       s1, c, ts, s2, tdiv((double)c, t2));
-       } else {/* bytes,ops,time,bytes/sec,ops/sec */
-               printf("%lld,%d,%s,%.3f,%.3f\n",
-                       total, c, ts,
-                       tdiv((double)total, t2), tdiv((double)c, t2));
-       }
-done:
-       free(args);
-       close(fd);
-       return 0;
-}
-
-void
-dedupe_init(void)
-{
-       dedupe_cmd.name = "dedupe";
-       dedupe_cmd.altname = "dd";
-       dedupe_cmd.cfunc = dedupe_f;
-       dedupe_cmd.argmin = 4;
-       dedupe_cmd.argmax = -1;
-       dedupe_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
-       dedupe_cmd.args =
-_("infile src_off dst_off len");
-       dedupe_cmd.oneline =
-               _("dedupes a number of bytes at a specified offset");
-       dedupe_cmd.help = dedupe_help;
-
-       add_command(&dedupe_cmd);
-}
index 739371e0fb5090bfb18199316b0b1e21bf4d1f53..51f1f5c96feb448f5dd0f0a4838f070e84e7d7eb 100644 (file)
--- a/io/init.c
+++ b/io/init.c
@@ -84,7 +84,6 @@ init_commands(void)
        sync_range_init();
        truncate_init();
        reflink_init();
-       dedupe_init();
 }
 
 static int
diff --git a/io/io.h b/io/io.h
index ec8a53089371e6b4fde5baf0010ec80af7be51ff..172b1f84760fbee677c5a330332ad3934aea4391 100644 (file)
--- a/io/io.h
+++ b/io/io.h
@@ -163,4 +163,3 @@ extern void         readdir_init(void);
 #endif
 
 extern void            reflink_init(void);
-extern void            dedupe_init(void);
index 0433537e8d38a26cde9c915d054c5cccbf738eb1..5ba1c93ad65b2fa1a175e6d708862719935fb7e0 100644 (file)
 #include "init.h"
 #include "io.h"
 
+static cmdinfo_t dedupe_cmd;
 static cmdinfo_t reflink_cmd;
 
+static void
+dedupe_help(void)
+{
+       printf(_("\n\
+ Links a range of bytes (in block size increments) from a file into a range\n\
+ of bytes in the open file.  The contents of both file ranges must match.\n\
+\n\
+ Example:\n\
+ 'dedupe some_file 0 4096 32768' - links 32768 bytes from some_file at\n\
+                                    offset 0 to into the open file at\n\
+                                    position 4096\n\
+\n\
+ Reflink a range of blocks from a given input file to the open file.  Both\n\
+ files share the same range of physical disk blocks; a write to the shared\n\
+ range of either file should result in the write landing in a new block and\n\
+ that range of the file being remapped (i.e. copy-on-write).  Both files\n\
+ must reside on the same filesystem, and the contents of both ranges must\n\
+ match.\n\
+"));
+}
+
+static uint64_t
+dedupe_ioctl(
+       int             fd,
+       uint64_t        soffset,
+       uint64_t        doffset,
+       uint64_t        len,
+       int             *ops)
+{
+       struct xfs_extent_data          *args;
+       struct xfs_extent_data_info     *info;
+       int                             error;
+       uint64_t                        deduped = 0;
+
+       args = calloc(1, sizeof(struct xfs_extent_data) +
+                        sizeof(struct xfs_extent_data_info));
+       if (!args)
+               goto done;
+       info = (struct xfs_extent_data_info *)(args + 1);
+       args->logical_offset = soffset;
+       args->length = len;
+       args->dest_count = 1;
+       info->fd = file->fd;
+       info->logical_offset = doffset;
+
+       while (args->length > 0) {
+               error = ioctl(fd, XFS_IOC_FILE_EXTENT_SAME, args);
+               if (error) {
+                       perror("XFS_IOC_FILE_EXTENT_SAME");
+                       goto done;
+               }
+               if (info->status < 0) {
+                       printf("dedupe: %s\n", _(strerror(-info->status)));
+                       goto done;
+               }
+               if (info->status == XFS_EXTENT_DATA_DIFFERS) {
+                       printf(_("Extents did not match.\n"));
+                       goto done;
+               }
+               if (info->bytes_deduped == 0 ||
+                   info->bytes_deduped > args->length)
+                       break;
+
+               (*ops)++;
+               args->logical_offset += info->bytes_deduped;
+               info->logical_offset += info->bytes_deduped;
+               args->length -= info->bytes_deduped;
+               deduped += info->bytes_deduped;
+       }
+done:
+       free(args);
+       return deduped;
+}
+
+static int
+dedupe_f(
+       int             argc,
+       char            **argv)
+{
+       off64_t         soffset, doffset;
+       long long       count, total;
+       char            *infile;
+       int             condensed, quiet_flag;
+       size_t          fsblocksize, fssectsize;
+       struct timeval  t1, t2;
+       int             c, ops = 0, fd = -1;
+
+       condensed = quiet_flag = 0;
+       init_cvtnum(&fsblocksize, &fssectsize);
+
+       while ((c = getopt(argc, argv, "Cq")) != EOF) {
+               switch (c) {
+               case 'C':
+                       condensed = 1;
+                       break;
+               case 'q':
+                       quiet_flag = 1;
+                       break;
+               default:
+                       return command_usage(&dedupe_cmd);
+               }
+       }
+       if (optind != argc - 4)
+               return command_usage(&dedupe_cmd);
+       infile = argv[optind];
+       optind++;
+       soffset = cvtnum(fsblocksize, fssectsize, argv[optind]);
+       if (soffset < 0) {
+               printf(_("non-numeric src offset argument -- %s\n"), argv[optind]);
+               return 0;
+       }
+       optind++;
+       doffset = cvtnum(fsblocksize, fssectsize, argv[optind]);
+       if (doffset < 0) {
+               printf(_("non-numeric dest offset argument -- %s\n"), argv[optind]);
+               return 0;
+       }
+       optind++;
+       count = cvtnum(fsblocksize, fssectsize, argv[optind]);
+       if (count < 1) {
+               printf(_("non-positive length argument -- %s\n"), argv[optind]);
+               return 0;
+       }
+
+       fd = openfile(infile, NULL, IO_READONLY, 0);
+       if (fd < 0)
+               return 0;
+
+       gettimeofday(&t1, NULL);
+       total = dedupe_ioctl(fd, soffset, doffset, count, &ops);
+       if (ops == 0 || quiet_flag)
+               goto done;
+       gettimeofday(&t2, NULL);
+       t2 = tsub(t2, t1);
+
+       report_io_times("deduped", &t2, (long long)doffset, count, total, ops,
+                       condensed);
+done:
+       close(fd);
+       return 0;
+}
+
 static void
 reflink_help(void)
 {
-       printf(_(
-"\n"
-" Links a range of bytes (in block size increments) from a file into a range \n"
-" of bytes in the open file.  The two extent ranges need not contain identical\n"
-" data. \n"
-"\n"
-" Example:\n"
-" 'reflink some_file 0 4096 32768' - links 32768 bytes from some_file at \n"
-"                                    offset 0 to into the open file at \n"
-"                                    position 4096\n"
-" 'reflink some_file' - links all bytes from some_file into the open file\n"
-"                       at position 0\n"
-"\n"
-" Reflink a range of blocks from a given input file to the open file.  Both\n"
-" files share the same range of physical disk blocks; a write to the shared\n"
-" range of either file should result in the write landing in a new block and\n"
-" that range of the file being remapped (i.e. copy-on-write).  Both files\n"
-" must reside on the same filesystem.\n"
-" -w   -- call fdatasync(2) at the end (included in timing results)\n"
-" -W   -- call fsync(2) at the end (included in timing results)\n"
-"\n"));
+       printf(_("\n\
+ Links a range of bytes (in block size increments) from a file into a range\n\
+ of bytes in the open file.  The two extent ranges need not contain identical\n\
+ data.\n\
+\n\
+ Example:\n\
+ 'reflink some_file 0 4096 32768' - links 32768 bytes from some_file at\n\
+                                    offset 0 to into the open file at\n\
+                                    position 4096\n\
+ 'reflink some_file' - links all bytes from some_file into the open file\n\
+                       at position 0\n\
+\n\
+ Reflink a range of blocks from a given input file to the open file.  Both\n\
+ files share the same range of physical disk blocks; a write to the shared\n\
+ range of either file should result in the write landing in a new block and\n\
+ that range of the file being remapped (i.e. copy-on-write).  Both files\n\
+ must reside on the same filesystem.\n\
+"));
+}
+
+static uint64_t
+reflink_ioctl(
+       int                     fd,
+       uint64_t                soffset,
+       uint64_t                doffset,
+       uint64_t                len,
+       int                     *ops)
+{
+       struct xfs_clone_args   args;
+       int                     error;
+
+       if (len) {
+               args.src_fd = fd;
+               args.src_offset = soffset;
+               args.src_length = len;
+               args.dest_offset = doffset;
+               error = ioctl(file->fd, XFS_IOC_CLONE_RANGE, &args);
+               if (error)
+                       perror("XFS_IOC_CLONE_RANGE");
+       } else {
+               error = ioctl(file->fd, XFS_IOC_CLONE, fd);
+               if (error)
+                       perror("XFS_IOC_CLONE");
+       }
+       if (!error)
+               (*ops)++;
+       return error ? 0 : len;
 }
 
 static int
@@ -56,32 +225,25 @@ reflink_f(
        int             argc,
        char            **argv)
 {
-       off64_t         soffset = 0, doffset = 0;
+       off64_t         soffset, doffset;
        long long       count = 0, total;
-       char            s1[64], s2[64], ts[64];
        char            *infile = NULL;
-       int             Cflag, qflag, wflag, Wflag;
-       struct xfs_ioctl_clone_range_args       args;
+       int             condensed, quiet_flag;
        size_t          fsblocksize, fssectsize;
        struct timeval  t1, t2;
-       int             c, fd = -1;
+       int             c, ops = 0, fd = -1;
 
-       Cflag = qflag = wflag = Wflag = 0;
+       condensed = quiet_flag = 0;
+       doffset = soffset = 0;
        init_cvtnum(&fsblocksize, &fssectsize);
 
-       while ((c = getopt(argc, argv, "CqwW")) != EOF) {
+       while ((c = getopt(argc, argv, "Cq")) != EOF) {
                switch (c) {
                case 'C':
-                       Cflag = 1;
+                       condensed = 1;
                        break;
                case 'q':
-                       qflag = 1;
-                       break;
-               case 'w':
-                       wflag = 1;
-                       break;
-               case 'W':
-                       Wflag = 1;
+                       quiet_flag = 1;
                        break;
                default:
                        return command_usage(&reflink_cmd);
@@ -112,50 +274,19 @@ reflink_f(
        }
 
 clone_all:
-       c = IO_READONLY;
-       fd = openfile(infile, NULL, c, 0);
+       fd = openfile(infile, NULL, IO_READONLY, 0);
        if (fd < 0)
                return 0;
 
        gettimeofday(&t1, NULL);
-       if (count) {
-               args.src_fd = fd;
-               args.src_offset = soffset;
-               args.src_length = count;
-               args.dest_offset = doffset;
-               c = ioctl(file->fd, XFS_IOC_CLONE_RANGE, &args);
-       } else {
-               c = ioctl(file->fd, XFS_IOC_CLONE, fd);
-       }
-       if (c < 0) {
-               perror(_("reflink"));
-               goto done;
-       }
-       total = count;
-       c = 1;
-       if (Wflag)
-               fsync(file->fd);
-       if (wflag)
-               fdatasync(file->fd);
-       if (qflag)
+       total = reflink_ioctl(fd, soffset, doffset, count, &ops);
+       if (ops == 0 || quiet_flag)
                goto done;
        gettimeofday(&t2, NULL);
        t2 = tsub(t2, t1);
 
-       /* Finally, report back -- -C gives a parsable format */
-       timestr(&t2, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0);
-       if (!Cflag) {
-               cvtstr((double)total, s1, sizeof(s1));
-               cvtstr(tdiv((double)total, t2), s2, sizeof(s2));
-               printf(_("linked %lld/%lld bytes at offset %lld\n"),
-                       total, count, (long long)doffset);
-               printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"),
-                       s1, c, ts, s2, tdiv((double)c, t2));
-       } else {/* bytes,ops,time,bytes/sec,ops/sec */
-               printf("%lld,%d,%s,%.3f,%.3f\n",
-                       total, c, ts,
-                       tdiv((double)total, t2), tdiv((double)c, t2));
-       }
+       report_io_times("linked", &t2, (long long)doffset, count, total, ops,
+                       condensed);
 done:
        close(fd);
        return 0;
@@ -177,4 +308,18 @@ _("infile src_off dst_off len");
        reflink_cmd.help = reflink_help;
 
        add_command(&reflink_cmd);
+
+       dedupe_cmd.name = "dedupe";
+       dedupe_cmd.altname = "dd";
+       dedupe_cmd.cfunc = dedupe_f;
+       dedupe_cmd.argmin = 4;
+       dedupe_cmd.argmax = -1;
+       dedupe_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
+       dedupe_cmd.args =
+_("infile src_off dst_off len");
+       dedupe_cmd.oneline =
+               _("dedupes a number of bytes at a specified offset");
+       dedupe_cmd.help = dedupe_help;
+
+       add_command(&dedupe_cmd);
 }
index c14903ed98b6b33613f553f1ad188d2d1a80beaf..d8b733ac4aac623988b66c23797ea0dbeab198bd 100644 (file)
@@ -569,41 +569,46 @@ typedef struct xfs_swapext
 /*     XFS_IOC_GETFSUUID ---------- deprecated 140      */
 
 /* reflink ioctls; these MUST match the btrfs ioctl definitions */
-struct xfs_ioctl_clone_range_args {
+/* from struct btrfs_ioctl_clone_range_args */
+struct xfs_clone_args {
        __s64 src_fd;
        __u64 src_offset;
        __u64 src_length;
        __u64 dest_offset;
 };
 
-#define XFS_SAME_DATA_DIFFERS  1
-/* For extent-same ioctl */
-struct xfs_ioctl_file_extent_same_info {
+/* extent-same (dedupe) ioctls; these MUST match the btrfs ioctl definitions */
+#define XFS_EXTENT_DATA_SAME   0
+#define XFS_EXTENT_DATA_DIFFERS        1
+
+/* from struct btrfs_ioctl_file_extent_same_info */
+struct xfs_extent_data_info {
        __s64 fd;               /* in - destination file */
        __u64 logical_offset;   /* in - start of extent in destination */
        __u64 bytes_deduped;    /* out - total # of bytes we were able
                                 * to dedupe from this file */
        /* status of this dedupe operation:
-        * 0 if dedup succeeds
         * < 0 for error
-        * == XFS_SAME_DATA_DIFFERS if data differs
+        * == XFS_EXTENT_DATA_SAME if dedupe succeeds
+        * == XFS_EXTENT_DATA_DIFFERS if data differs
         */
        __s32 status;           /* out - see above description */
        __u32 reserved;
 };
 
-struct xfs_ioctl_file_extent_same_args {
+/* from struct btrfs_ioctl_file_extent_same_args */
+struct xfs_extent_data {
        __u64 logical_offset;   /* in - start of extent in source */
        __u64 length;           /* in - length of extent */
        __u16 dest_count;       /* in - total elements in info array */
        __u16 reserved1;
        __u32 reserved2;
-       struct xfs_ioctl_file_extent_same_info info[0];
+       struct xfs_extent_data_info info[0];
 };
 
 #define XFS_IOC_CLONE           _IOW (0x94, 9, int)
-#define XFS_IOC_CLONE_RANGE     _IOW (0x94, 13, struct xfs_ioctl_clone_range_args)
-#define XFS_IOC_FILE_EXTENT_SAME _IOWR(0x94, 54, struct xfs_ioctl_file_extent_same_args)
+#define XFS_IOC_CLONE_RANGE     _IOW (0x94, 13, struct xfs_clone_args)
+#define XFS_IOC_FILE_EXTENT_SAME _IOWR(0x94, 54, struct xfs_extent_data)
 
 #ifndef HAVE_BBMACROS
 /*
index 305335c520c256707e17930e0cf93181af5ad50c..7fd74781060a5c64f800757b3500220d8b342501 100644 (file)
@@ -494,7 +494,7 @@ both data and holes are displayed together or performing a recusively display.
 .PD
 .TP
 .TP
-.BI "reflink  [ \-w ] [ \-W ] src_file [src_offset dst_offset length]"
+.BI "reflink  [ \-C ] [ \-q ] src_file [src_offset dst_offset length]"
 On filesystems that support the
 .B XFS_IOC_CLONE_RANGE
 or
@@ -515,20 +515,16 @@ are omitted, all contents of src_file will be reflinked into the open file.
 .RS 1.0i
 .PD 0
 .TP 0.4i
-.B \-w
-Call
-.BR fdatasync (2)
-after executing the ioctl.
+.B \-C
+Print timing statistics in a condensed format.
 .TP
-.B \-W
-Call
-.BR fsync (2)
-after executing the command.
+.B \-q
+Do not print timing statistics at all.
 .RE
 .PD
 .TP
 .TP
-.BI "dedupe  [ \-w ] [ \-W ] src_file src_offset dst_offset length"
+.BI "dedupe  [ \-C ] [ \-q ] src_file src_offset dst_offset length"
 On filesystems that support the
 .B XFS_IOC_FILE_EXTENT_SAME
 or
@@ -548,16 +544,11 @@ on write") in the affected file, leaving the other file(s) unchanged.
 .RS 1.0i
 .PD 0
 .TP 0.4i
-.B \-w
-Call
-.BR fdatasync (2)
-after executing the ioctl.
-.TP
-.B \-W
-Call
-.BR fsync (2)
-after executing the command.
+.B \-C
+Print timing statistics in a condensed format.
 .TP
+.B \-q
+Do not print timing statistics at all.
 
 .SH MEMORY MAPPED I/O COMMANDS
 .TP