btrfs: use btrfs_try_lock_balance in btrfs_ioctl_balance
authorNikolay Borisov <nborisov@suse.com>
Thu, 5 May 2022 07:08:25 +0000 (10:08 +0300)
committerDavid Sterba <dsterba@suse.com>
Mon, 25 Jul 2022 15:44:34 +0000 (17:44 +0200)
This eliminates 2 labels and makes the code generally more streamlined.
Also rename the 'out_bargs' label to 'out_unlock' since bargs is going
to be freed under the 'out' label. This also fixes a memory leak since
bargs wasn't correctly freed in one of the condition which are now moved
in btrfs_try_lock_balance.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/ioctl.c

index e40ce7a..679ce4c 100644 (file)
@@ -4427,7 +4427,7 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
        struct btrfs_fs_info *fs_info = root->fs_info;
        struct btrfs_ioctl_balance_args *bargs;
        struct btrfs_balance_control *bctl;
-       bool need_unlock; /* for mut. excl. ops lock */
+       bool need_unlock = true;
        int ret;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -4444,53 +4444,12 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
                goto out;
        }
 
-again:
-       if (btrfs_exclop_start(fs_info, BTRFS_EXCLOP_BALANCE)) {
-               mutex_lock(&fs_info->balance_mutex);
-               need_unlock = true;
-               goto locked;
-       }
-
-       /*
-        * mut. excl. ops lock is locked.  Three possibilities:
-        *   (1) some other op is running
-        *   (2) balance is running
-        *   (3) balance is paused -- special case (think resume)
-        */
-       mutex_lock(&fs_info->balance_mutex);
-       if (fs_info->balance_ctl) {
-               /* this is either (2) or (3) */
-               if (!test_bit(BTRFS_FS_BALANCE_RUNNING, &fs_info->flags)) {
-                       mutex_unlock(&fs_info->balance_mutex);
-                       /*
-                        * Lock released to allow other waiters to continue,
-                        * we'll reexamine the status again.
-                        */
-                       mutex_lock(&fs_info->balance_mutex);
-
-                       if (fs_info->balance_ctl &&
-                           !test_bit(BTRFS_FS_BALANCE_RUNNING, &fs_info->flags)) {
-                               /* this is (3) */
-                               need_unlock = false;
-                               goto locked;
-                       }
-
-                       mutex_unlock(&fs_info->balance_mutex);
-                       goto again;
-               } else {
-                       /* this is (2) */
-                       mutex_unlock(&fs_info->balance_mutex);
-                       ret = -EINPROGRESS;
-                       goto out;
-               }
-       } else {
-               /* this is (1) */
-               mutex_unlock(&fs_info->balance_mutex);
-               ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
+       ret = btrfs_try_lock_balance(fs_info, &need_unlock);
+       if (ret)
                goto out;
-       }
 
-locked:
+       lockdep_assert_held(&fs_info->balance_mutex);
+
        if (bargs->flags & BTRFS_BALANCE_RESUME) {
                if (!fs_info->balance_ctl) {
                        ret = -ENOTCONN;