aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 85e546ffe3c7..1e7a9bac31ab 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3065,7 +3065,7 @@ out:
3065 return ret; 3065 return ret;
3066} 3066}
3067 3067
3068void update_ioctl_balance_args(struct btrfs_fs_info *fs_info, 3068void update_ioctl_balance_args(struct btrfs_fs_info *fs_info, int lock,
3069 struct btrfs_ioctl_balance_args *bargs) 3069 struct btrfs_ioctl_balance_args *bargs)
3070{ 3070{
3071 struct btrfs_balance_control *bctl = fs_info->balance_ctl; 3071 struct btrfs_balance_control *bctl = fs_info->balance_ctl;
@@ -3082,6 +3082,14 @@ void update_ioctl_balance_args(struct btrfs_fs_info *fs_info,
3082 memcpy(&bargs->data, &bctl->data, sizeof(bargs->data)); 3082 memcpy(&bargs->data, &bctl->data, sizeof(bargs->data));
3083 memcpy(&bargs->meta, &bctl->meta, sizeof(bargs->meta)); 3083 memcpy(&bargs->meta, &bctl->meta, sizeof(bargs->meta));
3084 memcpy(&bargs->sys, &bctl->sys, sizeof(bargs->sys)); 3084 memcpy(&bargs->sys, &bctl->sys, sizeof(bargs->sys));
3085
3086 if (lock) {
3087 spin_lock(&fs_info->balance_lock);
3088 memcpy(&bargs->stat, &bctl->stat, sizeof(bargs->stat));
3089 spin_unlock(&fs_info->balance_lock);
3090 } else {
3091 memcpy(&bargs->stat, &bctl->stat, sizeof(bargs->stat));
3092 }
3085} 3093}
3086 3094
3087static long btrfs_ioctl_balance(struct btrfs_root *root, void __user *arg) 3095static long btrfs_ioctl_balance(struct btrfs_root *root, void __user *arg)
@@ -3181,6 +3189,39 @@ static long btrfs_ioctl_balance_ctl(struct btrfs_root *root, int cmd)
3181 return -EINVAL; 3189 return -EINVAL;
3182} 3190}
3183 3191
3192static long btrfs_ioctl_balance_progress(struct btrfs_root *root,
3193 void __user *arg)
3194{
3195 struct btrfs_fs_info *fs_info = root->fs_info;
3196 struct btrfs_ioctl_balance_args *bargs;
3197 int ret = 0;
3198
3199 if (!capable(CAP_SYS_ADMIN))
3200 return -EPERM;
3201
3202 mutex_lock(&fs_info->balance_mutex);
3203 if (!fs_info->balance_ctl) {
3204 ret = -ENOTCONN;
3205 goto out;
3206 }
3207
3208 bargs = kzalloc(sizeof(*bargs), GFP_NOFS);
3209 if (!bargs) {
3210 ret = -ENOMEM;
3211 goto out;
3212 }
3213
3214 update_ioctl_balance_args(fs_info, 1, bargs);
3215
3216 if (copy_to_user(arg, bargs, sizeof(*bargs)))
3217 ret = -EFAULT;
3218
3219 kfree(bargs);
3220out:
3221 mutex_unlock(&fs_info->balance_mutex);
3222 return ret;
3223}
3224
3184long btrfs_ioctl(struct file *file, unsigned int 3225long btrfs_ioctl(struct file *file, unsigned int
3185 cmd, unsigned long arg) 3226 cmd, unsigned long arg)
3186{ 3227{
@@ -3261,6 +3302,8 @@ long btrfs_ioctl(struct file *file, unsigned int
3261 return btrfs_ioctl_balance(root, argp); 3302 return btrfs_ioctl_balance(root, argp);
3262 case BTRFS_IOC_BALANCE_CTL: 3303 case BTRFS_IOC_BALANCE_CTL:
3263 return btrfs_ioctl_balance_ctl(root, arg); 3304 return btrfs_ioctl_balance_ctl(root, arg);
3305 case BTRFS_IOC_BALANCE_PROGRESS:
3306 return btrfs_ioctl_balance_progress(root, argp);
3264 } 3307 }
3265 3308
3266 return -ENOTTY; 3309 return -ENOTTY;