Commit 1baea6f1 authored by Filipe Manana's avatar Filipe Manana Committed by David Sterba

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: default avatarFilipe Manana <fdmanana@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent a2c8d27e
...@@ -1674,32 +1674,36 @@ int btrfs_find_all_leafs(struct btrfs_backref_walk_ctx *ctx) ...@@ -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 * the current while iterating. The process stops when we reach the end of the
* list. * list.
* *
* Found roots are added to @ctx->roots, which is allocated by this function and * Found roots are added to @ctx->roots, which is allocated by this function if
* @ctx->roots should be NULL when calling this function. This function also * it points to NULL, in which case the caller is responsible for freeing it
* requires @ctx->refs to be NULL, as it uses it for allocating a ulist to do * after it's not needed anymore.
* temporary work, and frees it before returning. * 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) static int btrfs_find_all_roots_safe(struct btrfs_backref_walk_ctx *ctx)
{ {
const u64 orig_bytenr = ctx->bytenr; const u64 orig_bytenr = ctx->bytenr;
const bool orig_ignore_extent_item_pos = ctx->ignore_extent_item_pos; const bool orig_ignore_extent_item_pos = ctx->ignore_extent_item_pos;
bool roots_ulist_allocated = false;
struct ulist_iterator uiter; struct ulist_iterator uiter;
int ret = 0; int ret = 0;
ASSERT(ctx->refs == NULL); ASSERT(ctx->refs == NULL);
ASSERT(ctx->roots == NULL);
ctx->refs = ulist_alloc(GFP_NOFS); ctx->refs = ulist_alloc(GFP_NOFS);
if (!ctx->refs) if (!ctx->refs)
return -ENOMEM; return -ENOMEM;
ctx->roots = ulist_alloc(GFP_NOFS);
if (!ctx->roots) { if (!ctx->roots) {
ulist_free(ctx->refs); ctx->roots = ulist_alloc(GFP_NOFS);
ctx->refs = NULL; if (!ctx->roots) {
return -ENOMEM; ulist_free(ctx->refs);
ctx->refs = NULL;
return -ENOMEM;
}
roots_ulist_allocated = true;
} }
ctx->ignore_extent_item_pos = true; ctx->ignore_extent_item_pos = true;
...@@ -1710,8 +1714,10 @@ static int btrfs_find_all_roots_safe(struct btrfs_backref_walk_ctx *ctx) ...@@ -1710,8 +1714,10 @@ static int btrfs_find_all_roots_safe(struct btrfs_backref_walk_ctx *ctx)
ret = find_parent_nodes(ctx, NULL); ret = find_parent_nodes(ctx, NULL);
if (ret < 0 && ret != -ENOENT) { if (ret < 0 && ret != -ENOENT) {
ulist_free(ctx->roots); if (roots_ulist_allocated) {
ctx->roots = NULL; ulist_free(ctx->roots);
ctx->roots = NULL;
}
break; break;
} }
ret = 0; ret = 0;
...@@ -2295,6 +2301,11 @@ int iterate_extent_inodes(struct btrfs_backref_walk_ctx *ctx, ...@@ -2295,6 +2301,11 @@ int iterate_extent_inodes(struct btrfs_backref_walk_ctx *ctx,
ctx->bytenr); ctx->bytenr);
ASSERT(ctx->trans == NULL); ASSERT(ctx->trans == NULL);
ASSERT(ctx->roots == NULL);
ctx->roots = ulist_alloc(GFP_NOFS);
if (!ctx->roots)
return -ENOMEM;
if (!search_commit_root) { if (!search_commit_root) {
struct btrfs_trans_handle *trans; struct btrfs_trans_handle *trans;
...@@ -2302,8 +2313,11 @@ int iterate_extent_inodes(struct btrfs_backref_walk_ctx *ctx, ...@@ -2302,8 +2313,11 @@ int iterate_extent_inodes(struct btrfs_backref_walk_ctx *ctx,
trans = btrfs_attach_transaction(ctx->fs_info->tree_root); trans = btrfs_attach_transaction(ctx->fs_info->tree_root);
if (IS_ERR(trans)) { if (IS_ERR(trans)) {
if (PTR_ERR(trans) != -ENOENT && if (PTR_ERR(trans) != -ENOENT &&
PTR_ERR(trans) != -EROFS) PTR_ERR(trans) != -EROFS) {
ulist_free(ctx->roots);
ctx->roots = NULL;
return PTR_ERR(trans); return PTR_ERR(trans);
}
trans = NULL; trans = NULL;
} }
ctx->trans = trans; ctx->trans = trans;
...@@ -2344,8 +2358,7 @@ int iterate_extent_inodes(struct btrfs_backref_walk_ctx *ctx, ...@@ -2344,8 +2358,7 @@ int iterate_extent_inodes(struct btrfs_backref_walk_ctx *ctx,
root_node->val, ctx->bytenr, root_node->val, ctx->bytenr,
iterate, user_ctx); iterate, user_ctx);
} }
ulist_free(ctx->roots); ulist_reinit(ctx->roots);
ctx->roots = NULL;
} }
free_leaf_list(refs); free_leaf_list(refs);
...@@ -2358,6 +2371,9 @@ int iterate_extent_inodes(struct btrfs_backref_walk_ctx *ctx, ...@@ -2358,6 +2371,9 @@ int iterate_extent_inodes(struct btrfs_backref_walk_ctx *ctx,
up_read(&ctx->fs_info->commit_root_sem); up_read(&ctx->fs_info->commit_root_sem);
} }
ulist_free(ctx->roots);
ctx->roots = NULL;
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment