From: David Sterba Date: Thu, 30 Apr 2026 15:25:01 +0000 (+0200) Subject: btrfs: use on stack backref iterator in build_backref_tree() X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=f84f833a72c73f33180d98258e35df3272decadc;p=thirdparty%2Flinux.git 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 --- diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 303f6cfc97c10..0abcec0ceead0 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 96717460e2e04..179791de6b195 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 843fdcacb3155..67af02e732d0c 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);