All of lore.kernel.org
 help / color / mirror / Atom feed
From: Filipe Manana <fdmanana@gmail.com>
To: David Sterba <dsterba@suse.com>
Cc: linux-btrfs <linux-btrfs@vger.kernel.org>
Subject: Re: [PATCH v2] btrfs: add cancellable chunk relocation support
Date: Thu, 17 Jun 2021 10:18:02 +0100	[thread overview]
Message-ID: <CAL3q7H6U2Usjk=sZ9r5uuaoLYD8REqE+pOezVhp1HrvoRNJNhQ@mail.gmail.com> (raw)
In-Reply-To: <20210616155828.13703-1-dsterba@suse.com>

On Wed, Jun 16, 2021 at 5:01 PM David Sterba <dsterba@suse.com> wrote:
>
> Add support code that will allow canceling relocation on the chunk
> granularity. This is different and independent of balance, that also
> uses relocation but is a higher level operation and manages it's own
> state and pause/cancellation requests.
>
> Relocation is used for resize (shrink) and device deletion so this will
> be a common point to implement cancellation for both. The context is
> entirely in btrfs_relocate_block_group and btrfs_recover_relocation,
> enclosing one chunk relocation. The status bit is set and unset between
> the chunks. As relocation can take long, the effects may not be
> immediate and the request and actual action can slightly race.
>
> The fs_info::reloc_cancel_req is only supposed to be increased and does
> not pair with decrement like fs_info::balance_cancel_req.
>
> Signed-off-by: David Sterba <dsterba@suse.com>
> ---
>
> v2:
> - put the blockgroup by the original pointer 'bg' in
>   btrfs_relocate_block_group

Reviewed-by: Filipe Manana <fdmanana@suse.com>

Looks good now, thanks.

>
>  fs/btrfs/ctree.h      |  9 +++++++
>  fs/btrfs/disk-io.c    |  1 +
>  fs/btrfs/relocation.c | 62 +++++++++++++++++++++++++++++++++++++++++--
>  3 files changed, 70 insertions(+), 2 deletions(-)
>
> diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
> index 4049f533e35e..b7c36aad45ef 100644
> --- a/fs/btrfs/ctree.h
> +++ b/fs/btrfs/ctree.h
> @@ -565,6 +565,12 @@ enum {
>          */
>         BTRFS_FS_BALANCE_RUNNING,
>
> +       /*
> +        * Indicate that relocation of a chunk has started, it's set per chunk
> +        * and is toggled between chunks.
> +        */
> +       BTRFS_FS_RELOC_RUNNING,
> +
>         /* Indicate that the cleaner thread is awake and doing something. */
>         BTRFS_FS_CLEANER_RUNNING,
>
> @@ -871,6 +877,9 @@ struct btrfs_fs_info {
>         struct btrfs_balance_control *balance_ctl;
>         wait_queue_head_t balance_wait_q;
>
> +       /* Cancellation requests for chunk relocation */
> +       atomic_t reloc_cancel_req;
> +
>         u32 data_chunk_allocations;
>         u32 metadata_ratio;
>
> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
> index 34bcd986f738..d1d5091a8385 100644
> --- a/fs/btrfs/disk-io.c
> +++ b/fs/btrfs/disk-io.c
> @@ -2251,6 +2251,7 @@ static void btrfs_init_balance(struct btrfs_fs_info *fs_info)
>         atomic_set(&fs_info->balance_cancel_req, 0);
>         fs_info->balance_ctl = NULL;
>         init_waitqueue_head(&fs_info->balance_wait_q);
> +       atomic_set(&fs_info->reloc_cancel_req, 0);
>  }
>
>  static void btrfs_init_btree_inode(struct btrfs_fs_info *fs_info)
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index b70be2ac2e9e..420a89869889 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -2876,11 +2876,12 @@ int setup_extent_mapping(struct inode *inode, u64 start, u64 end,
>  }
>
>  /*
> - * Allow error injection to test balance cancellation
> + * Allow error injection to test balance/relocation cancellation
>   */
>  noinline int btrfs_should_cancel_balance(struct btrfs_fs_info *fs_info)
>  {
>         return atomic_read(&fs_info->balance_cancel_req) ||
> +               atomic_read(&fs_info->reloc_cancel_req) ||
>                 fatal_signal_pending(current);
>  }
>  ALLOW_ERROR_INJECTION(btrfs_should_cancel_balance, TRUE);
> @@ -3780,6 +3781,47 @@ struct inode *create_reloc_inode(struct btrfs_fs_info *fs_info,
>         return inode;
>  }
>
> +/*
> + * Mark start of chunk relocation that is cancellable. Check if the cancellation
> + * has been requested meanwhile and don't start in that case.
> + *
> + * Return:
> + *   0             success
> + *   -EINPROGRESS  operation is already in progress, that's probably a bug
> + *   -ECANCELED    cancellation request was set before the operation started
> + */
> +static int reloc_chunk_start(struct btrfs_fs_info *fs_info)
> +{
> +       if (test_and_set_bit(BTRFS_FS_RELOC_RUNNING, &fs_info->flags)) {
> +               /* This should not happen */
> +               btrfs_err(fs_info, "reloc already running, cannot start");
> +               return -EINPROGRESS;
> +       }
> +
> +       if (atomic_read(&fs_info->reloc_cancel_req) > 0) {
> +               btrfs_info(fs_info, "chunk relocation canceled on start");
> +               /*
> +                * On cancel, clear all requests but let the caller mark
> +                * the end after cleanup operations.
> +                */
> +               atomic_set(&fs_info->reloc_cancel_req, 0);
> +               return -ECANCELED;
> +       }
> +       return 0;
> +}
> +
> +/*
> + * Mark end of chunk relocation that is cancellable and wake any waiters.
> + */
> +static void reloc_chunk_end(struct btrfs_fs_info *fs_info)
> +{
> +       /* Requested after start, clear bit first so any waiters can continue */
> +       if (atomic_read(&fs_info->reloc_cancel_req) > 0)
> +               btrfs_info(fs_info, "chunk relocation canceled during operation");
> +       clear_and_wake_up_bit(BTRFS_FS_RELOC_RUNNING, &fs_info->flags);
> +       atomic_set(&fs_info->reloc_cancel_req, 0);
> +}
> +
>  static struct reloc_control *alloc_reloc_control(struct btrfs_fs_info *fs_info)
>  {
>         struct reloc_control *rc;
> @@ -3862,6 +3904,12 @@ int btrfs_relocate_block_group(struct btrfs_fs_info *fs_info, u64 group_start)
>                 return -ENOMEM;
>         }
>
> +       ret = reloc_chunk_start(fs_info);
> +       if (ret < 0) {
> +               err = ret;
> +               goto out_put_bg;
> +       }
> +
>         rc->extent_root = extent_root;
>         rc->block_group = bg;
>
> @@ -3952,7 +4000,9 @@ int btrfs_relocate_block_group(struct btrfs_fs_info *fs_info, u64 group_start)
>         if (err && rw)
>                 btrfs_dec_block_group_ro(rc->block_group);
>         iput(rc->data_inode);
> -       btrfs_put_block_group(rc->block_group);
> +out_put_bg:
> +       btrfs_put_block_group(bg);
> +       reloc_chunk_end(fs_info);
>         free_reloc_control(rc);
>         return err;
>  }
> @@ -4073,6 +4123,12 @@ int btrfs_recover_relocation(struct btrfs_root *root)
>                 goto out;
>         }
>
> +       ret = reloc_chunk_start(fs_info);
> +       if (ret < 0) {
> +               err = ret;
> +               goto out_end;
> +       }
> +
>         rc->extent_root = fs_info->extent_root;
>
>         set_reloc_control(rc);
> @@ -4137,6 +4193,8 @@ int btrfs_recover_relocation(struct btrfs_root *root)
>                 err = ret;
>  out_unset:
>         unset_reloc_control(rc);
> +out_end:
> +       reloc_chunk_end(fs_info);
>         free_reloc_control(rc);
>  out:
>         free_reloc_roots(&reloc_roots);
> --
> 2.31.1
>


-- 
Filipe David Manana,

“Whether you think you can, or you think you can't — you're right.”

  reply	other threads:[~2021-06-17  9:18 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-21 12:06 [PATCH 0/6] Support resize and device delete cancel ops David Sterba
2021-05-21 12:06 ` [PATCH 1/6] btrfs: protect exclusive_operation by super_lock David Sterba
2021-05-21 13:37   ` Josef Bacik
2021-05-21 12:06 ` [PATCH 2/6] btrfs: add cancelable chunk relocation support David Sterba
2021-05-21 13:21   ` Josef Bacik
2021-05-26 22:56     ` David Sterba
2021-06-16 13:54   ` Filipe Manana
2021-06-16 13:55     ` Filipe Manana
2021-06-16 15:53       ` David Sterba
2021-06-16 15:58       ` [PATCH v2] btrfs: add cancellable " David Sterba
2021-06-17  9:18         ` Filipe Manana [this message]
2021-05-21 12:06 ` [PATCH 3/6] btrfs: introduce try-lock semantics for exclusive op start David Sterba
2021-05-21 13:38   ` Josef Bacik
2021-05-27  7:43   ` Anand Jain
2021-05-28 12:30     ` David Sterba
2021-05-29 13:48       ` Anand Jain
2021-05-31 18:23         ` David Sterba
2021-05-21 12:06 ` [PATCH 4/6] btrfs: add wrapper for conditional start of exclusive operation David Sterba
2021-05-21 13:29   ` Josef Bacik
2021-05-21 16:45     ` David Sterba
2021-05-26 22:24       ` David Sterba
2021-05-21 12:06 ` [PATCH 5/6] btrfs: add cancelation to resize David Sterba
2021-05-21 13:38   ` Josef Bacik
2021-05-21 12:06 ` [PATCH 6/6] btrfs: add device delete cancel David Sterba
2021-05-21 13:38   ` Josef Bacik
2021-05-21 12:06 ` [PATCH 1/2] btrfs-progs: device remove: add support for cancel David Sterba
2021-05-21 12:06 ` [PATCH 2/2] btrfs-progs: fi resize: " David Sterba
2021-12-14 14:49 ` [PATCH 0/6] Support resize and device delete cancel ops Anand Jain
2021-12-15 15:13   ` 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='CAL3q7H6U2Usjk=sZ9r5uuaoLYD8REqE+pOezVhp1HrvoRNJNhQ@mail.gmail.com' \
    --to=fdmanana@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.