]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: use on stack backref iterator in build_backref_tree()
authorDavid Sterba <dsterba@suse.com>
Thu, 30 Apr 2026 15:25:01 +0000 (17:25 +0200)
committerDavid Sterba <dsterba@suse.com>
Mon, 8 Jun 2026 13:53:32 +0000 (15:53 +0200)
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>
fs/btrfs/backref.c
fs/btrfs/backref.h
fs/btrfs/relocation.c

index 303f6cfc97c10d0b75a9c613910da7f0209917e8..0abcec0ceead0c02d39935623ee6de9770023669 100644 (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)
index 96717460e2e04d883a306517bfeabd0440c18396..179791de6b19556e3b134131ce5efb2440ae8ca0 100644 (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);
index 843fdcacb3155513654ee01bb295de461eb73b94..67af02e732d0ce9cbc40ace26ce84ae2d3c0d6d5 100644 (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);