forked from Minki/linux
btrfs: introduce btrfs_try_lock_balance
This function contains the factored out locking sequence of btrfs_ioctl_balance. Having this piece of code separate helps to simplify btrfs_ioctl_balance which has too complicated. This will be used in the next patch to streamline the logic in btrfs_ioctl_balance. 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
1e87770cb3
commit
7fb10ed89e
@ -4355,6 +4355,72 @@ void btrfs_update_ioctl_balance_args(struct btrfs_fs_info *fs_info,
|
||||
spin_unlock(&fs_info->balance_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to acquire fs_info::balance_mutex as well as set BTRFS_EXLCOP_BALANCE as
|
||||
* required.
|
||||
*
|
||||
* @fs_info: the filesystem
|
||||
* @excl_acquired: ptr to boolean value which is set to false in case balance
|
||||
* is being resumed
|
||||
*
|
||||
* Return 0 on success in which case both fs_info::balance is acquired as well
|
||||
* as exclusive ops are blocked. In case of failure return an error code.
|
||||
*/
|
||||
static int btrfs_try_lock_balance(struct btrfs_fs_info *fs_info, bool *excl_acquired)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Exclusive operation is locked. Three possibilities:
|
||||
* (1) some other op is running
|
||||
* (2) balance is running
|
||||
* (3) balance is paused -- special case (think resume)
|
||||
*/
|
||||
while (1) {
|
||||
if (btrfs_exclop_start(fs_info, BTRFS_EXCLOP_BALANCE)) {
|
||||
*excl_acquired = true;
|
||||
mutex_lock(&fs_info->balance_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)) {
|
||||
/* This is (2) */
|
||||
ret = -EINPROGRESS;
|
||||
goto out_failure;
|
||||
|
||||
} else {
|
||||
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) */
|
||||
*excl_acquired = false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* This is (1) */
|
||||
ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
|
||||
goto out_failure;
|
||||
}
|
||||
|
||||
mutex_unlock(&fs_info->balance_mutex);
|
||||
}
|
||||
|
||||
out_failure:
|
||||
mutex_unlock(&fs_info->balance_mutex);
|
||||
*excl_acquired = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long btrfs_ioctl_balance(struct file *file, void __user *arg)
|
||||
{
|
||||
struct btrfs_root *root = BTRFS_I(file_inode(file))->root;
|
||||
|
Loading…
Reference in New Issue
Block a user