btrfs: use on stack backref iterator in build_backref_tree()

The iterator is used only once and within build_backref_tree() so we can
avoid one allocation and place it on stack.

Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
David Sterba
2026-04-30 17:25:01 +02:00
parent be516b2d3c
commit f84f833a72
3 changed files with 15 additions and 24 deletions

View File

@@ -2814,25 +2814,17 @@ struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root,
return ifp;
}
struct btrfs_backref_iter *btrfs_backref_iter_alloc(void)
int btrfs_backref_iter_init(struct btrfs_backref_iter *iter)
{
struct btrfs_backref_iter *ret;
ret = kzalloc_obj(*ret, GFP_NOFS);
if (!ret)
return NULL;
ret->path = btrfs_alloc_path();
if (!ret->path) {
kfree(ret);
return NULL;
}
iter->path = btrfs_alloc_path();
if (!iter->path)
return -ENOMEM;
/* Current backref iterator only supports iteration in commit root */
ret->path->search_commit_root = true;
ret->path->skip_locking = true;
iter->path->search_commit_root = true;
iter->path->skip_locking = true;
return ret;
return 0;
}
static void btrfs_backref_iter_release(struct btrfs_backref_iter *iter)

View File

@@ -284,8 +284,6 @@ struct btrfs_backref_iter {
u32 end_ptr;
};
struct btrfs_backref_iter *btrfs_backref_iter_alloc(void);
/*
* For metadata with EXTENT_ITEM key (non-skinny) case, the first inline data
* is btrfs_tree_block_info, without a btrfs_extent_inline_ref header.
@@ -301,6 +299,8 @@ static inline bool btrfs_backref_has_tree_block_info(
return false;
}
int btrfs_backref_iter_init(struct btrfs_backref_iter *iter);
int btrfs_backref_iter_start(struct btrfs_fs_info *fs_info, struct btrfs_backref_iter *iter, u64 bytenr);
int btrfs_backref_iter_next(struct btrfs_fs_info *fs_info, struct btrfs_backref_iter *iter);

View File

@@ -407,7 +407,7 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
struct reloc_control *rc, struct btrfs_key *node_key,
int level, u64 bytenr)
{
struct btrfs_backref_iter *iter;
struct btrfs_backref_iter iter;
struct btrfs_backref_cache *cache = &rc->backref_cache;
/* For searching parent of TREE_BLOCK_REF */
struct btrfs_path *path;
@@ -416,9 +416,9 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
struct btrfs_backref_edge *edge;
int ret;
iter = btrfs_backref_iter_alloc();
if (!iter)
return ERR_PTR(-ENOMEM);
ret = btrfs_backref_iter_init(&iter);
if (ret < 0)
return ERR_PTR(ret);
path = btrfs_alloc_path();
if (!path) {
ret = -ENOMEM;
@@ -435,7 +435,7 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
/* Breadth-first search to build backref cache */
do {
ret = btrfs_backref_add_tree_node(trans, cache, path, iter,
ret = btrfs_backref_add_tree_node(trans, cache, path, &iter,
node_key, cur);
if (ret < 0)
goto out;
@@ -460,8 +460,7 @@ static noinline_for_stack struct btrfs_backref_node *build_backref_tree(
if (handle_useless_nodes(rc, node))
node = NULL;
out:
btrfs_free_path(iter->path);
kfree(iter);
btrfs_free_path(iter.path);
btrfs_free_path(path);
if (ret) {
btrfs_backref_error_cleanup(cache, node);