Commit d8645462 authored by Nikolay Borisov's avatar Nikolay Borisov Committed by David Sterba

btrfs: simplify code flow in btrfs_ioctl_balance

Move code in btrfs_ioctl_balance to simplify its flow. This is
possible thanks to the removal of balance v1 ioctl and ensuring 'arg'
argument is always present. First move the code duplicating the
userspace arg to the kernel 'barg'. This makes the out_unlock label
redundant.  Secondly, check the validity of bargs::flags before copying
to the dynamically allocated 'bctl'. This removes the need for the
out_bctl label.
Reviewed-by: default avatarSweet Tea Dorminy <sweettea-kernel@dorminy.me>
Signed-off-by: default avatarNikolay Borisov <nborisov@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 39864601
...@@ -4353,6 +4353,13 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg) ...@@ -4353,6 +4353,13 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
if (ret) if (ret)
return ret; return ret;
bargs = memdup_user(arg, sizeof(*bargs));
if (IS_ERR(bargs)) {
ret = PTR_ERR(bargs);
bargs = NULL;
goto out;
}
again: again:
if (btrfs_exclop_start(fs_info, BTRFS_EXCLOP_BALANCE)) { if (btrfs_exclop_start(fs_info, BTRFS_EXCLOP_BALANCE)) {
mutex_lock(&fs_info->balance_mutex); mutex_lock(&fs_info->balance_mutex);
...@@ -4400,17 +4407,10 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg) ...@@ -4400,17 +4407,10 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
} }
locked: locked:
bargs = memdup_user(arg, sizeof(*bargs));
if (IS_ERR(bargs)) {
ret = PTR_ERR(bargs);
goto out_unlock;
}
if (bargs->flags & BTRFS_BALANCE_RESUME) { if (bargs->flags & BTRFS_BALANCE_RESUME) {
if (!fs_info->balance_ctl) { if (!fs_info->balance_ctl) {
ret = -ENOTCONN; ret = -ENOTCONN;
goto out_bargs; goto out_unlock;
} }
bctl = fs_info->balance_ctl; bctl = fs_info->balance_ctl;
...@@ -4422,15 +4422,20 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg) ...@@ -4422,15 +4422,20 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
goto do_balance; goto do_balance;
} }
if (bargs->flags & ~(BTRFS_BALANCE_ARGS_MASK | BTRFS_BALANCE_TYPE_MASK)) {
ret = -EINVAL;
goto out_unlock;
}
if (fs_info->balance_ctl) { if (fs_info->balance_ctl) {
ret = -EINPROGRESS; ret = -EINPROGRESS;
goto out_bargs; goto out_unlock;
} }
bctl = kzalloc(sizeof(*bctl), GFP_KERNEL); bctl = kzalloc(sizeof(*bctl), GFP_KERNEL);
if (!bctl) { if (!bctl) {
ret = -ENOMEM; ret = -ENOMEM;
goto out_bargs; goto out_unlock;
} }
memcpy(&bctl->data, &bargs->data, sizeof(bctl->data)); memcpy(&bctl->data, &bargs->data, sizeof(bctl->data));
...@@ -4438,12 +4443,6 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg) ...@@ -4438,12 +4443,6 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
memcpy(&bctl->sys, &bargs->sys, sizeof(bctl->sys)); memcpy(&bctl->sys, &bargs->sys, sizeof(bctl->sys));
bctl->flags = bargs->flags; bctl->flags = bargs->flags;
if (bctl->flags & ~(BTRFS_BALANCE_ARGS_MASK | BTRFS_BALANCE_TYPE_MASK)) {
ret = -EINVAL;
goto out_bctl;
}
do_balance: do_balance:
/* /*
* Ownership of bctl and exclusive operation goes to btrfs_balance. * Ownership of bctl and exclusive operation goes to btrfs_balance.
...@@ -4461,16 +4460,14 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg) ...@@ -4461,16 +4460,14 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
ret = -EFAULT; ret = -EFAULT;
} }
out_bctl:
kfree(bctl); kfree(bctl);
out_bargs:
kfree(bargs);
out_unlock: out_unlock:
mutex_unlock(&fs_info->balance_mutex); mutex_unlock(&fs_info->balance_mutex);
if (need_unlock) if (need_unlock)
btrfs_exclop_finish(fs_info); btrfs_exclop_finish(fs_info);
out: out:
mnt_drop_write_file(file); mnt_drop_write_file(file);
kfree(bargs);
return ret; return ret;
} }
......
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