btrfs: join DEV_STATS ioctls to one
authorDavid Sterba <dsterba@suse.cz>
Fri, 22 Jun 2012 12:30:39 +0000 (06:30 -0600)
committerChris Mason <chris.mason@fusionio.com>
Mon, 23 Jul 2012 19:41:40 +0000 (15:41 -0400)
Commit c11d2c236cc260b36 (Btrfs: add ioctl to get and reset the device
stats) introduced two ioctls doing almost the same thing distinguished
by just the ioctl number which encodes "do reset after read". I have
suggested

http://www.mail-archive.com/linux-btrfs@vger.kernel.org/msg16604.html

to implement it via the ioctl args. This hasn't happen, and I think we
should use a more clean way to pass flags and should not waste ioctl
numbers.

CC: Stefan Behrens <sbehrens@giantdisaster.de>
Signed-off-by: David Sterba <dsterba@suse.cz>
fs/btrfs/ioctl.c
fs/btrfs/ioctl.h
fs/btrfs/volumes.c
fs/btrfs/volumes.h

index 9ec23b93e019d2af98bde3c99edde6f01c13f073..3a3f916d7c02783ef00c1dbf2e51a6d56a9e484f 100644 (file)
@@ -3065,19 +3065,21 @@ static long btrfs_ioctl_scrub_progress(struct btrfs_root *root,
 }
 
 static long btrfs_ioctl_get_dev_stats(struct btrfs_root *root,
-                                     void __user *arg, int reset_after_read)
+                                     void __user *arg)
 {
        struct btrfs_ioctl_get_dev_stats *sa;
        int ret;
 
-       if (reset_after_read && !capable(CAP_SYS_ADMIN))
-               return -EPERM;
-
        sa = memdup_user(arg, sizeof(*sa));
        if (IS_ERR(sa))
                return PTR_ERR(sa);
 
-       ret = btrfs_get_dev_stats(root, sa, reset_after_read);
+       if ((sa->flags & BTRFS_DEV_STATS_RESET) && !capable(CAP_SYS_ADMIN)) {
+               kfree(sa);
+               return -EPERM;
+       }
+
+       ret = btrfs_get_dev_stats(root, sa);
 
        if (copy_to_user(arg, sa, sizeof(*sa)))
                ret = -EFAULT;
@@ -3475,9 +3477,7 @@ long btrfs_ioctl(struct file *file, unsigned int
        case BTRFS_IOC_BALANCE_PROGRESS:
                return btrfs_ioctl_balance_progress(root, argp);
        case BTRFS_IOC_GET_DEV_STATS:
-               return btrfs_ioctl_get_dev_stats(root, argp, 0);
-       case BTRFS_IOC_GET_AND_RESET_DEV_STATS:
-               return btrfs_ioctl_get_dev_stats(root, argp, 1);
+               return btrfs_ioctl_get_dev_stats(root, argp);
        }
 
        return -ENOTTY;
index e440aa653c30d6f6c8ad1e7437bfa6e2b4d50799..021c55ed8aed929f5a0d5a03ca94f76490e2779e 100644 (file)
@@ -285,9 +285,13 @@ enum btrfs_dev_stat_values {
        BTRFS_DEV_STAT_VALUES_MAX
 };
 
+/* Reset statistics after reading; needs SYS_ADMIN capability */
+#define        BTRFS_DEV_STATS_RESET           (1ULL << 0)
+
 struct btrfs_ioctl_get_dev_stats {
        __u64 devid;                            /* in */
        __u64 nr_items;                         /* in/out */
+       __u64 flags;                            /* in/out */
 
        /* out values: */
        __u64 values[BTRFS_DEV_STAT_VALUES_MAX];
@@ -361,7 +365,5 @@ struct btrfs_ioctl_get_dev_stats {
                                        struct btrfs_ioctl_ino_path_args)
 #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \
                                      struct btrfs_ioctl_get_dev_stats)
-#define BTRFS_IOC_GET_AND_RESET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 53, \
-                                       struct btrfs_ioctl_get_dev_stats)
 
 #endif
index ecaad40e7ef499fedb7667659d9efd955a661eaa..957bf393ab466bb64d63176c07f959e63fd8d43c 100644 (file)
@@ -4890,8 +4890,7 @@ static void btrfs_dev_stat_print_on_load(struct btrfs_device *dev)
 }
 
 int btrfs_get_dev_stats(struct btrfs_root *root,
-                       struct btrfs_ioctl_get_dev_stats *stats,
-                       int reset_after_read)
+                       struct btrfs_ioctl_get_dev_stats *stats)
 {
        struct btrfs_device *dev;
        struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices;
@@ -4909,7 +4908,7 @@ int btrfs_get_dev_stats(struct btrfs_root *root,
                printk(KERN_WARNING
                       "btrfs: get dev_stats failed, not yet valid\n");
                return -ENODEV;
-       } else if (reset_after_read) {
+       } else if (stats->flags & BTRFS_DEV_STATS_RESET) {
                for (i = 0; i < BTRFS_DEV_STAT_VALUES_MAX; i++) {
                        if (stats->nr_items > i)
                                stats->values[i] =
index 95f6637614db5932f8d52daba79943514a7ed8da..e404414a95a9ae0802f22f99dc68eab99198f812 100644 (file)
@@ -293,8 +293,7 @@ struct btrfs_device *btrfs_find_device_for_logical(struct btrfs_root *root,
 void btrfs_dev_stat_print_on_error(struct btrfs_device *device);
 void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index);
 int btrfs_get_dev_stats(struct btrfs_root *root,
-                       struct btrfs_ioctl_get_dev_stats *stats,
-                       int reset_after_read);
+                       struct btrfs_ioctl_get_dev_stats *stats);
 int btrfs_init_dev_stats(struct btrfs_fs_info *fs_info);
 int btrfs_run_dev_stats(struct btrfs_trans_handle *trans,
                        struct btrfs_fs_info *fs_info);