linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Anand Jain <anand.jain@oracle.com>
To: David Sterba <dsterba@suse.com>, linux-btrfs@vger.kernel.org
Subject: Re: [PATCH] btrfs: track exclusive filesystem operation in flags
Date: Wed, 29 Mar 2017 18:01:37 +0800	[thread overview]
Message-ID: <ac95c9c4-ed2b-3a9f-f763-697bd63db56f@oracle.com> (raw)
In-Reply-To: <20170328124421.30585-1-dsterba@suse.com>



On 03/28/2017 08:44 PM, David Sterba wrote:
> There are several operations, usually started from ioctls, that cannot
> run concurrently. The status is tracked in
> mutually_exclusive_operation_running as an atomic_t. We can easily track
> the status as one of the per-filesystem flag bits with same
> synchronization guarantees.
>
> The conversion replaces:
>
> * atomic_xchg(..., 1)    ->   test_and_set_bit(FLAG, ...)
> * atomic_set(..., 0)     ->   clear_bit(FLAG, ...)


    Makes sense.

   Reviewed-by: Anand Jain <anand.jain@oracle.com>

    However in the long term do you think its better to have
    BTRFS_FS_EXCL_OP flag in the struct btrfs_fs_devices
    rather than in struct btrfs_fs_info ? because we don't have
    fs_info until device is mounted and in the long term we could
    have a feature where volume can be maintained just after the
    device scan without device being mounted.

Thanks, Anand



> Signed-off-by: David Sterba <dsterba@suse.com>
> ---
>  fs/btrfs/ctree.h       |  7 +++++--
>  fs/btrfs/dev-replace.c |  5 ++---
>  fs/btrfs/ioctl.c       | 33 +++++++++++++++------------------
>  fs/btrfs/volumes.c     |  6 +++---
>  4 files changed, 25 insertions(+), 26 deletions(-)
>
> diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
> index 29b7fc28c607..2521752c4e4a 100644
> --- a/fs/btrfs/ctree.h
> +++ b/fs/btrfs/ctree.h
> @@ -702,6 +702,11 @@ struct btrfs_delayed_root;
>  #define BTRFS_FS_BTREE_ERR			11
>  #define BTRFS_FS_LOG1_ERR			12
>  #define BTRFS_FS_LOG2_ERR			13
> +/*
> + * Indicate that a whole-filesystem exclusive operation is running
> + * (device replace, resize, device add/delete, balance)
> + */
> +#define BTRFS_FS_EXCL_OP			14
>
>  struct btrfs_fs_info {
>  	u8 fsid[BTRFS_FSID_SIZE];
> @@ -1067,8 +1072,6 @@ struct btrfs_fs_info {
>  	/* device replace state */
>  	struct btrfs_dev_replace dev_replace;
>
> -	atomic_t mutually_exclusive_operation_running;
> -
>  	struct percpu_counter bio_counter;
>  	wait_queue_head_t replace_wait;
>
> diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
> index e653921f05d9..de7b2c897fe0 100644
> --- a/fs/btrfs/dev-replace.c
> +++ b/fs/btrfs/dev-replace.c
> @@ -784,8 +784,7 @@ int btrfs_resume_dev_replace_async(struct btrfs_fs_info *fs_info)
>  	}
>  	btrfs_dev_replace_unlock(dev_replace, 1);
>
> -	WARN_ON(atomic_xchg(
> -		&fs_info->mutually_exclusive_operation_running, 1));
> +	WARN_ON(test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags));
>  	task = kthread_run(btrfs_dev_replace_kthread, fs_info, "btrfs-devrepl");
>  	return PTR_ERR_OR_ZERO(task);
>  }
> @@ -814,7 +813,7 @@ static int btrfs_dev_replace_kthread(void *data)
>  			(unsigned int)progress);
>  	}
>  	btrfs_dev_replace_continue_on_mount(fs_info);
> -	atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
> +	clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags);
>
>  	return 0;
>  }
> diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
> index dabfc7ac48a6..a29dc3fd7152 100644
> --- a/fs/btrfs/ioctl.c
> +++ b/fs/btrfs/ioctl.c
> @@ -1504,7 +1504,7 @@ static noinline int btrfs_ioctl_resize(struct file *file,
>  	if (ret)
>  		return ret;
>
> -	if (atomic_xchg(&fs_info->mutually_exclusive_operation_running, 1)) {
> +	if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) {
>  		mnt_drop_write_file(file);
>  		return BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
>  	}
> @@ -1619,7 +1619,7 @@ static noinline int btrfs_ioctl_resize(struct file *file,
>  	kfree(vol_args);
>  out:
>  	mutex_unlock(&fs_info->volume_mutex);
> -	atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
> +	clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags);
>  	mnt_drop_write_file(file);
>  	return ret;
>  }
> @@ -2661,7 +2661,7 @@ static long btrfs_ioctl_add_dev(struct btrfs_fs_info *fs_info, void __user *arg)
>  	if (!capable(CAP_SYS_ADMIN))
>  		return -EPERM;
>
> -	if (atomic_xchg(&fs_info->mutually_exclusive_operation_running, 1))
> +	if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags))
>  		return BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
>
>  	mutex_lock(&fs_info->volume_mutex);
> @@ -2680,7 +2680,7 @@ static long btrfs_ioctl_add_dev(struct btrfs_fs_info *fs_info, void __user *arg)
>  	kfree(vol_args);
>  out:
>  	mutex_unlock(&fs_info->volume_mutex);
> -	atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
> +	clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags);
>  	return ret;
>  }
>
> @@ -2708,7 +2708,7 @@ static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg)
>  	if (vol_args->flags & ~BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED)
>  		return -EOPNOTSUPP;
>
> -	if (atomic_xchg(&fs_info->mutually_exclusive_operation_running, 1)) {
> +	if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) {
>  		ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
>  		goto out;
>  	}
> @@ -2721,7 +2721,7 @@ static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg)
>  		ret = btrfs_rm_device(fs_info, vol_args->name, 0);
>  	}
>  	mutex_unlock(&fs_info->volume_mutex);
> -	atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
> +	clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags);
>
>  	if (!ret) {
>  		if (vol_args->flags & BTRFS_DEVICE_SPEC_BY_ID)
> @@ -2752,7 +2752,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
>  	if (ret)
>  		return ret;
>
> -	if (atomic_xchg(&fs_info->mutually_exclusive_operation_running, 1)) {
> +	if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) {
>  		ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
>  		goto out_drop_write;
>  	}
> @@ -2772,7 +2772,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
>  		btrfs_info(fs_info, "disk deleted %s", vol_args->name);
>  	kfree(vol_args);
>  out:
> -	atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
> +	clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags);
>  out_drop_write:
>  	mnt_drop_write_file(file);
>
> @@ -4442,13 +4442,11 @@ static long btrfs_ioctl_dev_replace(struct btrfs_fs_info *fs_info,
>  			ret = -EROFS;
>  			goto out;
>  		}
> -		if (atomic_xchg(
> -			&fs_info->mutually_exclusive_operation_running, 1)) {
> +		if (test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) {
>  			ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
>  		} else {
>  			ret = btrfs_dev_replace_by_ioctl(fs_info, p);
> -			atomic_set(
> -			 &fs_info->mutually_exclusive_operation_running, 0);
> +			clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags);
>  		}
>  		break;
>  	case BTRFS_IOCTL_DEV_REPLACE_CMD_STATUS:
> @@ -4643,7 +4641,7 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
>  		return ret;
>
>  again:
> -	if (!atomic_xchg(&fs_info->mutually_exclusive_operation_running, 1)) {
> +	if (!test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags)) {
>  		mutex_lock(&fs_info->volume_mutex);
>  		mutex_lock(&fs_info->balance_mutex);
>  		need_unlock = true;
> @@ -4689,7 +4687,7 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
>  	}
>
>  locked:
> -	BUG_ON(!atomic_read(&fs_info->mutually_exclusive_operation_running));
> +	BUG_ON(!test_bit(BTRFS_FS_EXCL_OP, &fs_info->flags));
>
>  	if (arg) {
>  		bargs = memdup_user(arg, sizeof(*bargs));
> @@ -4745,11 +4743,10 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
>
>  do_balance:
>  	/*
> -	 * Ownership of bctl and mutually_exclusive_operation_running
> +	 * Ownership of bctl and filesystem flag BTRFS_FS_EXCL_OP
>  	 * goes to to btrfs_balance.  bctl is freed in __cancel_balance,
>  	 * or, if restriper was paused all the way until unmount, in
> -	 * free_fs_info.  mutually_exclusive_operation_running is
> -	 * cleared in __cancel_balance.
> +	 * free_fs_info.  The flag is cleared in __cancel_balance.
>  	 */
>  	need_unlock = false;
>
> @@ -4769,7 +4766,7 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg)
>  	mutex_unlock(&fs_info->balance_mutex);
>  	mutex_unlock(&fs_info->volume_mutex);
>  	if (need_unlock)
> -		atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
> +		clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags);
>  out:
>  	mnt_drop_write_file(file);
>  	return ret;
> diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
> index 73d56eef5e60..91580cf471e4 100644
> --- a/fs/btrfs/volumes.c
> +++ b/fs/btrfs/volumes.c
> @@ -3736,7 +3736,7 @@ static void __cancel_balance(struct btrfs_fs_info *fs_info)
>  	if (ret)
>  		btrfs_handle_fs_error(fs_info, ret, NULL);
>
> -	atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
> +	clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags);
>  }
>
>  /* Non-zero return value signifies invalidity */
> @@ -3910,7 +3910,7 @@ int btrfs_balance(struct btrfs_balance_control *bctl,
>  		__cancel_balance(fs_info);
>  	else {
>  		kfree(bctl);
> -		atomic_set(&fs_info->mutually_exclusive_operation_running, 0);
> +		clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags);
>  	}
>  	return ret;
>  }
> @@ -4000,7 +4000,7 @@ int btrfs_recover_balance(struct btrfs_fs_info *fs_info)
>  	btrfs_balance_sys(leaf, item, &disk_bargs);
>  	btrfs_disk_balance_args_to_cpu(&bctl->sys, &disk_bargs);
>
> -	WARN_ON(atomic_xchg(&fs_info->mutually_exclusive_operation_running, 1));
> +	WARN_ON(test_and_set_bit(BTRFS_FS_EXCL_OP, &fs_info->flags));
>
>  	mutex_lock(&fs_info->volume_mutex);
>  	mutex_lock(&fs_info->balance_mutex);
>

  reply	other threads:[~2017-03-29  9:56 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-28 12:44 [PATCH] btrfs: track exclusive filesystem operation in flags David Sterba
2017-03-29 10:01 ` Anand Jain [this message]
2017-03-29 13:21   ` David Sterba

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ac95c9c4-ed2b-3a9f-f763-697bd63db56f@oracle.com \
    --to=anand.jain@oracle.com \
    --cc=dsterba@suse.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).