Commit b27f7c0c authored by David Sterba's avatar David Sterba Committed by Chris Mason

btrfs: join DEV_STATS ioctls to one

Commit c11d2c23 (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: default avatarDavid Sterba <dsterba@suse.cz>
parent a43a2111
...@@ -3065,19 +3065,21 @@ static long btrfs_ioctl_scrub_progress(struct btrfs_root *root, ...@@ -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, 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; struct btrfs_ioctl_get_dev_stats *sa;
int ret; int ret;
if (reset_after_read && !capable(CAP_SYS_ADMIN))
return -EPERM;
sa = memdup_user(arg, sizeof(*sa)); sa = memdup_user(arg, sizeof(*sa));
if (IS_ERR(sa)) if (IS_ERR(sa))
return PTR_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))) if (copy_to_user(arg, sa, sizeof(*sa)))
ret = -EFAULT; ret = -EFAULT;
...@@ -3475,9 +3477,7 @@ long btrfs_ioctl(struct file *file, unsigned int ...@@ -3475,9 +3477,7 @@ long btrfs_ioctl(struct file *file, unsigned int
case BTRFS_IOC_BALANCE_PROGRESS: case BTRFS_IOC_BALANCE_PROGRESS:
return btrfs_ioctl_balance_progress(root, argp); return btrfs_ioctl_balance_progress(root, argp);
case BTRFS_IOC_GET_DEV_STATS: case BTRFS_IOC_GET_DEV_STATS:
return btrfs_ioctl_get_dev_stats(root, argp, 0); return btrfs_ioctl_get_dev_stats(root, argp);
case BTRFS_IOC_GET_AND_RESET_DEV_STATS:
return btrfs_ioctl_get_dev_stats(root, argp, 1);
} }
return -ENOTTY; return -ENOTTY;
......
...@@ -285,9 +285,13 @@ enum btrfs_dev_stat_values { ...@@ -285,9 +285,13 @@ enum btrfs_dev_stat_values {
BTRFS_DEV_STAT_VALUES_MAX 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 { struct btrfs_ioctl_get_dev_stats {
__u64 devid; /* in */ __u64 devid; /* in */
__u64 nr_items; /* in/out */ __u64 nr_items; /* in/out */
__u64 flags; /* in/out */
/* out values: */ /* out values: */
__u64 values[BTRFS_DEV_STAT_VALUES_MAX]; __u64 values[BTRFS_DEV_STAT_VALUES_MAX];
...@@ -361,7 +365,5 @@ struct btrfs_ioctl_get_dev_stats { ...@@ -361,7 +365,5 @@ struct btrfs_ioctl_get_dev_stats {
struct btrfs_ioctl_ino_path_args) struct btrfs_ioctl_ino_path_args)
#define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \ #define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \
struct btrfs_ioctl_get_dev_stats) 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 #endif
...@@ -4890,8 +4890,7 @@ static void btrfs_dev_stat_print_on_load(struct btrfs_device *dev) ...@@ -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, int btrfs_get_dev_stats(struct btrfs_root *root,
struct btrfs_ioctl_get_dev_stats *stats, struct btrfs_ioctl_get_dev_stats *stats)
int reset_after_read)
{ {
struct btrfs_device *dev; struct btrfs_device *dev;
struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices;
...@@ -4909,7 +4908,7 @@ int btrfs_get_dev_stats(struct btrfs_root *root, ...@@ -4909,7 +4908,7 @@ int btrfs_get_dev_stats(struct btrfs_root *root,
printk(KERN_WARNING printk(KERN_WARNING
"btrfs: get dev_stats failed, not yet valid\n"); "btrfs: get dev_stats failed, not yet valid\n");
return -ENODEV; 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++) { for (i = 0; i < BTRFS_DEV_STAT_VALUES_MAX; i++) {
if (stats->nr_items > i) if (stats->nr_items > i)
stats->values[i] = stats->values[i] =
......
...@@ -293,8 +293,7 @@ struct btrfs_device *btrfs_find_device_for_logical(struct btrfs_root *root, ...@@ -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_print_on_error(struct btrfs_device *device);
void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index); void btrfs_dev_stat_inc_and_print(struct btrfs_device *dev, int index);
int btrfs_get_dev_stats(struct btrfs_root *root, int btrfs_get_dev_stats(struct btrfs_root *root,
struct btrfs_ioctl_get_dev_stats *stats, struct btrfs_ioctl_get_dev_stats *stats);
int reset_after_read);
int btrfs_init_dev_stats(struct btrfs_fs_info *fs_info); int btrfs_init_dev_stats(struct btrfs_fs_info *fs_info);
int btrfs_run_dev_stats(struct btrfs_trans_handle *trans, int btrfs_run_dev_stats(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info); struct btrfs_fs_info *fs_info);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment