Commit 17aaa434 authored by David Sterba's avatar David Sterba

btrfs: add wrapper for conditional start of exclusive operation

To support optional cancellation of some operations, add helper that will
wrap all the combinations. In normal mode it's same as
btrfs_exclop_start, in cancellation mode it checks if it's already
running and request cancellation and waits until completion.

The error codes can be returned to to user space and semantics is not
changed, adding ECANCELED. This should be evaluated as an error and that
the operation has not completed and the operation should be restarted
or the filesystem status reviewed.
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 578bda9e
......@@ -1600,6 +1600,48 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
return ret;
}
/*
* Try to start exclusive operation @type or cancel it if it's running.
*
* Return:
* 0 - normal mode, newly claimed op started
* >0 - normal mode, something else is running,
* return BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS to user space
* ECANCELED - cancel mode, successful cancel
* ENOTCONN - cancel mode, operation not running anymore
*/
static int exclop_start_or_cancel_reloc(struct btrfs_fs_info *fs_info,
enum btrfs_exclusive_operation type, bool cancel)
{
if (!cancel) {
/* Start normal op */
if (!btrfs_exclop_start(fs_info, type))
return BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
/* Exclusive operation is now claimed */
return 0;
}
/* Cancel running op */
if (btrfs_exclop_start_try_lock(fs_info, type)) {
/*
* This blocks any exclop finish from setting it to NONE, so we
* request cancellation. Either it runs and we will wait for it,
* or it has finished and no waiting will happen.
*/
atomic_inc(&fs_info->reloc_cancel_req);
btrfs_exclop_start_unlock(fs_info);
if (test_bit(BTRFS_FS_RELOC_RUNNING, &fs_info->flags))
wait_on_bit(&fs_info->flags, BTRFS_FS_RELOC_RUNNING,
TASK_INTERRUPTIBLE);
return -ECANCELED;
}
/* Something else is running or none */
return -ENOTCONN;
}
static noinline int btrfs_ioctl_resize(struct file *file,
void __user *arg)
{
......
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