if (ret)
                return ret;
 
+       bargs = memdup_user(arg, sizeof(*bargs));
+       if (IS_ERR(bargs)) {
+               ret = PTR_ERR(bargs);
+               bargs = NULL;
+               goto out;
+       }
+
 again:
        if (btrfs_exclop_start(fs_info, BTRFS_EXCLOP_BALANCE)) {
                mutex_lock(&fs_info->balance_mutex);
        }
 
 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 (!fs_info->balance_ctl) {
                        ret = -ENOTCONN;
-                       goto out_bargs;
+                       goto out_unlock;
                }
 
                bctl = fs_info->balance_ctl;
                goto do_balance;
        }
 
+       if (bargs->flags & ~(BTRFS_BALANCE_ARGS_MASK | BTRFS_BALANCE_TYPE_MASK)) {
+               ret = -EINVAL;
+               goto out_unlock;
+       }
+
        if (fs_info->balance_ctl) {
                ret = -EINPROGRESS;
-               goto out_bargs;
+               goto out_unlock;
        }
 
        bctl = kzalloc(sizeof(*bctl), GFP_KERNEL);
        if (!bctl) {
                ret = -ENOMEM;
-               goto out_bargs;
+               goto out_unlock;
        }
 
        memcpy(&bctl->data, &bargs->data, sizeof(bctl->data));
        memcpy(&bctl->sys, &bargs->sys, sizeof(bctl->sys));
 
        bctl->flags = bargs->flags;
-
-       if (bctl->flags & ~(BTRFS_BALANCE_ARGS_MASK | BTRFS_BALANCE_TYPE_MASK)) {
-               ret = -EINVAL;
-               goto out_bctl;
-       }
-
 do_balance:
        /*
         * Ownership of bctl and exclusive operation goes to btrfs_balance.
                        ret = -EFAULT;
        }
 
-out_bctl:
        kfree(bctl);
-out_bargs:
-       kfree(bargs);
 out_unlock:
        mutex_unlock(&fs_info->balance_mutex);
        if (need_unlock)
                btrfs_exclop_finish(fs_info);
 out:
        mnt_drop_write_file(file);
+       kfree(bargs);
        return ret;
 }