summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2026-04-30 17:25:01 +0200
committerDavid Sterba <dsterba@suse.com>2026-06-08 15:53:32 +0200
commitf84f833a72c73f33180d98258e35df3272decadc (patch)
treeba1f9c498848c94e728fbda8fe4b26caecc111be
parentbe516b2d3c438a0c6dc934e797419fefae24a86e (diff)
downloadlinux-f84f833a72c73f33180d98258e35df3272decadc.tar.gz
linux-f84f833a72c73f33180d98258e35df3272decadc.zip
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>
-rw-r--r--fs/btrfs/backref.c22
-rw-r--r--fs/btrfs/backref.h4
-rw-r--r--fs/btrfs/relocation.c13
3 files changed, 15 insertions, 24 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 303f6cfc97c1..0abcec0ceead 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -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)
diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h
index 96717460e2e0..179791de6b19 100644
--- a/fs/btrfs/backref.h
+++ b/fs/btrfs/backref.h
@@ -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);
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 843fdcacb315..67af02e732d0 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -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);