btrfs: reuse roots ulist on each leaf iteration for iterate_extent_inodes()
At iterate_extent_inodes() we collect a ulist of leaves for a given extent with a call to btrfs_find_all_leafs() and then we enter a loop where we iterate over all the collected leaves. Each iteration of that loop does a call to btrfs_find_all_roots_safe(), to determine all roots from which a leaf is accessible, and that results in allocating and releasing a ulist to store the root IDs. Instead of allocating and releasing the roots ulist on every iteration, allocate a ulist before entering the loop and keep using it on each iteration, reinitializing the ulist at the end of each iteration. Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
a2c8d27e5e
commit
1baea6f18a
|
@ -1674,32 +1674,36 @@ int btrfs_find_all_leafs(struct btrfs_backref_walk_ctx *ctx)
|
|||
* the current while iterating. The process stops when we reach the end of the
|
||||
* list.
|
||||
*
|
||||
* Found roots are added to @ctx->roots, which is allocated by this function and
|
||||
* @ctx->roots should be NULL when calling this function. This function also
|
||||
* requires @ctx->refs to be NULL, as it uses it for allocating a ulist to do
|
||||
* temporary work, and frees it before returning.
|
||||
* Found roots are added to @ctx->roots, which is allocated by this function if
|
||||
* it points to NULL, in which case the caller is responsible for freeing it
|
||||
* after it's not needed anymore.
|
||||
* This function requires @ctx->refs to be NULL, as it uses it for allocating a
|
||||
* ulist to do temporary work, and frees it before returning.
|
||||
*
|
||||
* Returns 0 on success, < 0 on error. On error @ctx->roots is always NULL.
|
||||
* Returns 0 on success, < 0 on error.
|
||||
*/
|
||||
static int btrfs_find_all_roots_safe(struct btrfs_backref_walk_ctx *ctx)
|
||||
{
|
||||
const u64 orig_bytenr = ctx->bytenr;
|
||||
const bool orig_ignore_extent_item_pos = ctx->ignore_extent_item_pos;
|
||||
bool roots_ulist_allocated = false;
|
||||
struct ulist_iterator uiter;
|
||||
int ret = 0;
|
||||
|
||||
ASSERT(ctx->refs == NULL);
|
||||
ASSERT(ctx->roots == NULL);
|
||||
|
||||
ctx->refs = ulist_alloc(GFP_NOFS);
|
||||
if (!ctx->refs)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->roots = ulist_alloc(GFP_NOFS);
|
||||
if (!ctx->roots) {
|
||||
ulist_free(ctx->refs);
|
||||
ctx->refs = NULL;
|
||||
return -ENOMEM;
|
||||
ctx->roots = ulist_alloc(GFP_NOFS);
|
||||
if (!ctx->roots) {
|
||||
ulist_free(ctx->refs);
|
||||
ctx->refs = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
roots_ulist_allocated = true;
|
||||
}
|
||||
|
||||
ctx->ignore_extent_item_pos = true;
|
||||
|
@ -1710,8 +1714,10 @@ static int btrfs_find_all_roots_safe(struct btrfs_backref_walk_ctx *ctx)
|
|||
|
||||
ret = find_parent_nodes(ctx, NULL);
|
||||
if (ret < 0 && ret != -ENOENT) {
|
||||
ulist_free(ctx->roots);
|
||||
ctx->roots = NULL;
|
||||
if (roots_ulist_allocated) {
|
||||
ulist_free(ctx->roots);
|
||||
ctx->roots = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ret = 0;
|
||||
|
@ -2295,6 +2301,11 @@ int iterate_extent_inodes(struct btrfs_backref_walk_ctx *ctx,
|
|||
ctx->bytenr);
|
||||
|
||||
ASSERT(ctx->trans == NULL);
|
||||
ASSERT(ctx->roots == NULL);
|
||||
|
||||
ctx->roots = ulist_alloc(GFP_NOFS);
|
||||
if (!ctx->roots)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!search_commit_root) {
|
||||
struct btrfs_trans_handle *trans;
|
||||
|
@ -2302,8 +2313,11 @@ int iterate_extent_inodes(struct btrfs_backref_walk_ctx *ctx,
|
|||
trans = btrfs_attach_transaction(ctx->fs_info->tree_root);
|
||||
if (IS_ERR(trans)) {
|
||||
if (PTR_ERR(trans) != -ENOENT &&
|
||||
PTR_ERR(trans) != -EROFS)
|
||||
PTR_ERR(trans) != -EROFS) {
|
||||
ulist_free(ctx->roots);
|
||||
ctx->roots = NULL;
|
||||
return PTR_ERR(trans);
|
||||
}
|
||||
trans = NULL;
|
||||
}
|
||||
ctx->trans = trans;
|
||||
|
@ -2344,8 +2358,7 @@ int iterate_extent_inodes(struct btrfs_backref_walk_ctx *ctx,
|
|||
root_node->val, ctx->bytenr,
|
||||
iterate, user_ctx);
|
||||
}
|
||||
ulist_free(ctx->roots);
|
||||
ctx->roots = NULL;
|
||||
ulist_reinit(ctx->roots);
|
||||
}
|
||||
|
||||
free_leaf_list(refs);
|
||||
|
@ -2358,6 +2371,9 @@ out:
|
|||
up_read(&ctx->fs_info->commit_root_sem);
|
||||
}
|
||||
|
||||
ulist_free(ctx->roots);
|
||||
ctx->roots = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue