mirror of
https://github.com/torvalds/linux.git
synced 2024-12-01 08:31:37 +00:00
btrfs: allow device add if balance is paused
Currently paused balance precludes adding a device since they are both considered exclusive ops and we can have at most one running at a time. This is problematic in case a filesystem encounters an ENOSPC situation while balance is running, in this case the only thing the user can do is mount the fs with "skip_balance" which pauses balance and delete some data to free up space for balance. However, it should be possible to add a new device when balance is paused. Fix this by allowing device add to proceed when balance is paused. Signed-off-by: Nikolay Borisov <nborisov@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
621a1ee1d3
commit
a174c0a2e8
@ -3174,13 +3174,25 @@ out:
|
||||
static long btrfs_ioctl_add_dev(struct btrfs_fs_info *fs_info, void __user *arg)
|
||||
{
|
||||
struct btrfs_ioctl_vol_args *vol_args;
|
||||
bool restore_op = false;
|
||||
int ret;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_DEV_ADD))
|
||||
return BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
|
||||
if (!btrfs_exclop_start(fs_info, BTRFS_EXCLOP_DEV_ADD)) {
|
||||
if (!btrfs_exclop_start_try_lock(fs_info, BTRFS_EXCLOP_DEV_ADD))
|
||||
return BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
|
||||
|
||||
/*
|
||||
* We can do the device add because we have a paused balanced,
|
||||
* change the exclusive op type and remember we should bring
|
||||
* back the paused balance
|
||||
*/
|
||||
fs_info->exclusive_operation = BTRFS_EXCLOP_DEV_ADD;
|
||||
btrfs_exclop_start_unlock(fs_info);
|
||||
restore_op = true;
|
||||
}
|
||||
|
||||
vol_args = memdup_user(arg, sizeof(*vol_args));
|
||||
if (IS_ERR(vol_args)) {
|
||||
@ -3196,7 +3208,10 @@ static long btrfs_ioctl_add_dev(struct btrfs_fs_info *fs_info, void __user *arg)
|
||||
|
||||
kfree(vol_args);
|
||||
out:
|
||||
btrfs_exclop_finish(fs_info);
|
||||
if (restore_op)
|
||||
btrfs_exclop_balance(fs_info, BTRFS_EXCLOP_BALANCE_PAUSED);
|
||||
else
|
||||
btrfs_exclop_finish(fs_info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user