Commit 562d4254 authored by Josef Bacik's avatar Josef Bacik Committed by David Sterba

btrfs: factor out eb uptodate check from do_walk_down()

do_walk_down() already has a bunch of things going on, and there's a bit
of code related to reading in the next eb if we decide we need it.  Move
this code off into it's own helper to clean up do_walk_down() a little
bit.
Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 7fcee18d
...@@ -5409,6 +5409,48 @@ static int check_ref_exists(struct btrfs_trans_handle *trans, ...@@ -5409,6 +5409,48 @@ static int check_ref_exists(struct btrfs_trans_handle *trans,
return 1; return 1;
} }
/*
* We may not have an uptodate block, so if we are going to walk down into this
* block we need to drop the lock, read it off of the disk, re-lock it and
* return to continue dropping the snapshot.
*/
static int check_next_block_uptodate(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct btrfs_path *path,
struct walk_control *wc,
struct extent_buffer *next)
{
struct btrfs_tree_parent_check check = { 0 };
u64 generation;
int level = wc->level;
int ret;
btrfs_assert_tree_write_locked(next);
generation = btrfs_node_ptr_generation(path->nodes[level], path->slots[level]);
if (btrfs_buffer_uptodate(next, generation, 0))
return 0;
check.level = level - 1;
check.transid = generation;
check.owner_root = btrfs_root_id(root);
check.has_first_key = true;
btrfs_node_key_to_cpu(path->nodes[level], &check.first_key, path->slots[level]);
btrfs_tree_unlock(next);
if (level == 1)
reada_walk_down(trans, root, wc, path);
ret = btrfs_read_extent_buffer(next, &check);
if (ret) {
free_extent_buffer(next);
return ret;
}
btrfs_tree_lock(next);
wc->lookup_info = 1;
return 0;
}
/* /*
* helper to process tree block pointer. * helper to process tree block pointer.
* *
...@@ -5431,7 +5473,6 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, ...@@ -5431,7 +5473,6 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
u64 bytenr; u64 bytenr;
u64 generation; u64 generation;
u64 owner_root = 0; u64 owner_root = 0;
struct btrfs_tree_parent_check check = { 0 };
struct btrfs_key key; struct btrfs_key key;
struct extent_buffer *next; struct extent_buffer *next;
int level = wc->level; int level = wc->level;
...@@ -5453,13 +5494,6 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, ...@@ -5453,13 +5494,6 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
bytenr = btrfs_node_blockptr(path->nodes[level], path->slots[level]); bytenr = btrfs_node_blockptr(path->nodes[level], path->slots[level]);
check.level = level - 1;
check.transid = generation;
check.owner_root = btrfs_root_id(root);
check.has_first_key = true;
btrfs_node_key_to_cpu(path->nodes[level], &check.first_key,
path->slots[level]);
next = btrfs_find_create_tree_block(fs_info, bytenr, btrfs_root_id(root), next = btrfs_find_create_tree_block(fs_info, bytenr, btrfs_root_id(root),
level - 1); level - 1);
if (IS_ERR(next)) if (IS_ERR(next))
...@@ -5507,18 +5541,9 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, ...@@ -5507,18 +5541,9 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
goto skip; goto skip;
} }
if (!btrfs_buffer_uptodate(next, generation, 0)) { ret = check_next_block_uptodate(trans, root, path, wc, next);
btrfs_tree_unlock(next); if (ret)
if (level == 1) return ret;
reada_walk_down(trans, root, wc, path);
ret = btrfs_read_extent_buffer(next, &check);
if (ret) {
free_extent_buffer(next);
return ret;
}
btrfs_tree_lock(next);
wc->lookup_info = 1;
}
level--; level--;
ASSERT(level == btrfs_header_level(next)); ASSERT(level == btrfs_header_level(next));
......
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