|
@@ -3046,6 +3046,28 @@ static long btrfs_ioctl_scrub_progress(struct btrfs_root *root,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static long btrfs_ioctl_get_dev_stats(struct btrfs_root *root,
|
|
|
+ void __user *arg, int reset_after_read)
|
|
|
+{
|
|
|
+ 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 (copy_to_user(arg, sa, sizeof(*sa)))
|
|
|
+ ret = -EFAULT;
|
|
|
+
|
|
|
+ kfree(sa);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static long btrfs_ioctl_ino_to_path(struct btrfs_root *root, void __user *arg)
|
|
|
{
|
|
|
int ret = 0;
|
|
@@ -3434,6 +3456,10 @@ long btrfs_ioctl(struct file *file, unsigned int
|
|
|
return btrfs_ioctl_balance_ctl(root, arg);
|
|
|
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 -ENOTTY;
|