From: Boris Burkov <boris@bur.io>
To: Josef Bacik <josef@toxicpanda.com>
Cc: linux-btrfs@vger.kernel.org, kernel-team@fb.com
Subject: Re: [PATCH 06/10] btrfs: don't build backref tree for cowonly blocks
Date: Thu, 3 Oct 2024 14:36:00 -0700 [thread overview]
Message-ID: <20241003213600.GD435178@zen.localdomain> (raw)
In-Reply-To: <b92ec1ed0dc070a6c07f0a42197ea71fc34fdf05.1727970063.git.josef@toxicpanda.com>
On Thu, Oct 03, 2024 at 11:43:08AM -0400, Josef Bacik wrote:
> We already determine the owner for any blocks we find when we're
> relocating, and for cowonly blocks (and the data reloc tree) we cow down
> to the block and call it good enough. However we still build a whole
> backref tree for them, even though we're not going to use it, and then
> just don't put these blocks in the cache.
>
> Rework the code to check if the block belongs to a cowonly root or the
> data reloc root, and then just cow down to the block, skipping the
> backref cache generation.
>
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> ---
> fs/btrfs/relocation.c | 89 ++++++++++++++++++++++++++++++++++---------
> 1 file changed, 70 insertions(+), 19 deletions(-)
>
> diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
> index 7de94e55234c..db5f6bda93c9 100644
> --- a/fs/btrfs/relocation.c
> +++ b/fs/btrfs/relocation.c
> @@ -2136,17 +2136,11 @@ static noinline_for_stack u64 calcu_metadata_size(struct reloc_control *rc,
> return num_bytes;
> }
>
> -static int reserve_metadata_space(struct btrfs_trans_handle *trans,
> - struct reloc_control *rc,
> - struct btrfs_backref_node *node)
> +static int refill_metadata_space(struct btrfs_trans_handle *trans,
> + struct reloc_control *rc, u64 num_bytes)
> {
> - struct btrfs_root *root = rc->extent_root;
> - struct btrfs_fs_info *fs_info = root->fs_info;
> - u64 num_bytes;
> + struct btrfs_fs_info *fs_info = trans->fs_info;
> int ret;
> - u64 tmp;
> -
> - num_bytes = calcu_metadata_size(rc, node) * 2;
>
> trans->block_rsv = rc->block_rsv;
> rc->reserved_bytes += num_bytes;
> @@ -2159,7 +2153,7 @@ static int reserve_metadata_space(struct btrfs_trans_handle *trans,
> ret = btrfs_block_rsv_refill(fs_info, rc->block_rsv, num_bytes,
> BTRFS_RESERVE_FLUSH_LIMIT);
> if (ret) {
> - tmp = fs_info->nodesize * RELOCATION_RESERVED_NODES;
> + u64 tmp = fs_info->nodesize * RELOCATION_RESERVED_NODES;
> while (tmp <= rc->reserved_bytes)
> tmp <<= 1;
> /*
> @@ -2177,6 +2171,16 @@ static int reserve_metadata_space(struct btrfs_trans_handle *trans,
> return 0;
> }
>
> +static int reserve_metadata_space(struct btrfs_trans_handle *trans,
> + struct reloc_control *rc,
> + struct btrfs_backref_node *node)
> +{
> + u64 num_bytes;
> +
> + num_bytes = calcu_metadata_size(rc, node) * 2;
> + return refill_metadata_space(trans, rc, num_bytes);
> +}
> +
> /*
> * relocate a block tree, and then update pointers in upper level
> * blocks that reference the block to point to the new location.
> @@ -2528,15 +2532,11 @@ static int relocate_tree_block(struct btrfs_trans_handle *trans,
> node->root = btrfs_grab_root(root);
> ASSERT(node->root);
> } else {
> - path->lowest_level = node->level;
> - if (root == root->fs_info->chunk_root)
> - btrfs_reserve_chunk_metadata(trans, false);
> - ret = btrfs_search_slot(trans, root, key, path, 0, 1);
> - btrfs_release_path(path);
> - if (root == root->fs_info->chunk_root)
> - btrfs_trans_release_chunk_metadata(trans);
> - if (ret > 0)
> - ret = 0;
> + btrfs_err(root->fs_info,
> + "bytenr %llu resolved to a non-shareable root",
> + node->bytenr);
> + ret = -EUCLEAN;
> + goto out;
> }
> if (!ret)
> update_processed_blocks(rc, node);
> @@ -2549,6 +2549,43 @@ static int relocate_tree_block(struct btrfs_trans_handle *trans,
> return ret;
> }
>
> +static noinline_for_stack
> +int relocate_cowonly_block(struct btrfs_trans_handle *trans,
> + struct reloc_control *rc, struct tree_block *block,
> + struct btrfs_path *path)
> +{
> + struct btrfs_fs_info *fs_info = trans->fs_info;
> + struct btrfs_root *root;
> + u64 num_bytes;
> + int nr_levels;
> + int ret;
> +
> + root = btrfs_get_fs_root(fs_info, block->owner, true);
> + if (IS_ERR(root))
> + return PTR_ERR(root);
> +
> + nr_levels = max(btrfs_header_level(root->node) - block->level, 0) + 1;
> +
> + num_bytes = fs_info->nodesize * nr_levels;
> + ret = refill_metadata_space(trans, rc, num_bytes);
> + if (ret) {
> + btrfs_put_root(root);
> + return ret;
> + }
> + path->lowest_level = block->level;
> + if (root == root->fs_info->chunk_root)
> + btrfs_reserve_chunk_metadata(trans, false);
> + ret = btrfs_search_slot(trans, root, &block->key, path, 0, 1);
> + path->lowest_level = 0;
> + btrfs_release_path(path);
> + if (root == root->fs_info->chunk_root)
> + btrfs_trans_release_chunk_metadata(trans);
> + if (ret > 0)
> + ret = 0;
> + btrfs_put_root(root);
> + return ret;
> +}
> +
> /*
> * relocate a list of blocks
> */
> @@ -2588,6 +2625,20 @@ int relocate_tree_blocks(struct btrfs_trans_handle *trans,
>
> /* Do tree relocation */
> rbtree_postorder_for_each_entry_safe(block, next, blocks, rb_node) {
> + /*
> + * For cowonly blocks, or the data reloc tree, we only need to
> + * cow down to the block, there's no need to generate a backref
> + * tree.
> + */
> + if (block->owner &&
> + (!is_fstree(block->owner) ||
> + block->owner == BTRFS_DATA_RELOC_TREE_OBJECTID)) {
would it make sense to capture this (and probably other conditions using
roots instead of backref cache blocks) into a named cowonly concept?
> + ret = relocate_cowonly_block(trans, rc, block, path);
> + if (ret)
> + break;
> + continue;
> + }
> +
> node = build_backref_tree(trans, rc, &block->key,
> block->level, block->bytenr);
> if (IS_ERR(node)) {
> --
> 2.43.0
>
next prev parent reply other threads:[~2024-10-03 21:36 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-03 15:43 [PATCH 00/10] btrfs: backref cache cleanups Josef Bacik
2024-10-03 15:43 ` [PATCH 01/10] btrfs: convert BUG_ON in btrfs_reloc_cow_block to proper error handling Josef Bacik
2024-10-08 17:29 ` David Sterba
2024-10-03 15:43 ` [PATCH 02/10] btrfs: remove the changed list for backref cache Josef Bacik
2024-10-03 15:43 ` [PATCH 03/10] btrfs: add a comment for new_bytenr in bacref_cache_node Josef Bacik
2024-10-03 21:34 ` Boris Burkov
2024-10-03 15:43 ` [PATCH 04/10] btrfs: cleanup select_reloc_root Josef Bacik
2024-10-03 21:27 ` Boris Burkov
2024-10-03 15:43 ` [PATCH 05/10] btrfs: remove clone_backref_node Josef Bacik
2024-10-03 15:43 ` [PATCH 06/10] btrfs: don't build backref tree for cowonly blocks Josef Bacik
2024-10-03 21:36 ` Boris Burkov [this message]
2024-10-03 15:43 ` [PATCH 07/10] btrfs: do not handle non-shareable roots in backref cache Josef Bacik
2024-10-03 15:43 ` [PATCH 08/10] btrfs: simplify btrfs_backref_release_cache Josef Bacik
2024-10-03 15:43 ` [PATCH 09/10] btrfs: remove the ->lowest and ->leaves members from backref cache Josef Bacik
2024-10-03 15:43 ` [PATCH 10/10] btrfs: remove detached list from btrfs_backref_cache Josef Bacik
2024-10-03 21:39 ` [PATCH 00/10] btrfs: backref cache cleanups Boris Burkov
2024-12-06 19:38 ` David Sterba
2024-12-09 14:01 ` Josef Bacik
2024-12-10 23:24 ` 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=20241003213600.GD435178@zen.localdomain \
--to=boris@bur.io \
--cc=josef@toxicpanda.com \
--cc=kernel-team@fb.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.