mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-11-20 08:38:24 +08:00
Btrfs: use the right node in reada_for_balance
reada_for_balance was using the wrong index into the path node array, so it wasn't reading the right blocks. We never directly used the results of the read done by this function because the btree search is started over at the end. This fixes reada_for_balance to reada in the correct node and to avoid searching past the last slot in the node. It also makes sure to hold the parent lock while we are finding the nodes to read. Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
11c8349b4e
commit
8c594ea81d
@ -1325,12 +1325,12 @@ static noinline int reada_for_balance(struct btrfs_root *root,
|
||||
int ret = 0;
|
||||
int blocksize;
|
||||
|
||||
parent = path->nodes[level - 1];
|
||||
parent = path->nodes[level + 1];
|
||||
if (!parent)
|
||||
return 0;
|
||||
|
||||
nritems = btrfs_header_nritems(parent);
|
||||
slot = path->slots[level];
|
||||
slot = path->slots[level + 1];
|
||||
blocksize = btrfs_level_size(root, level);
|
||||
|
||||
if (slot > 0) {
|
||||
@ -1341,7 +1341,7 @@ static noinline int reada_for_balance(struct btrfs_root *root,
|
||||
block1 = 0;
|
||||
free_extent_buffer(eb);
|
||||
}
|
||||
if (slot < nritems) {
|
||||
if (slot + 1 < nritems) {
|
||||
block2 = btrfs_node_blockptr(parent, slot + 1);
|
||||
gen = btrfs_node_ptr_generation(parent, slot + 1);
|
||||
eb = btrfs_find_tree_block(root, block2, blocksize);
|
||||
@ -1351,7 +1351,11 @@ static noinline int reada_for_balance(struct btrfs_root *root,
|
||||
}
|
||||
if (block1 || block2) {
|
||||
ret = -EAGAIN;
|
||||
|
||||
/* release the whole path */
|
||||
btrfs_release_path(root, path);
|
||||
|
||||
/* read the blocks */
|
||||
if (block1)
|
||||
readahead_tree_block(root, block1, blocksize, 0);
|
||||
if (block2)
|
||||
@ -1361,7 +1365,7 @@ static noinline int reada_for_balance(struct btrfs_root *root,
|
||||
eb = read_tree_block(root, block1, blocksize, 0);
|
||||
free_extent_buffer(eb);
|
||||
}
|
||||
if (block1) {
|
||||
if (block2) {
|
||||
eb = read_tree_block(root, block2, blocksize, 0);
|
||||
free_extent_buffer(eb);
|
||||
}
|
||||
@ -1481,12 +1485,15 @@ read_block_for_search(struct btrfs_trans_handle *trans,
|
||||
* of the btree by dropping locks before
|
||||
* we read.
|
||||
*/
|
||||
btrfs_release_path(NULL, p);
|
||||
btrfs_unlock_up_safe(p, level + 1);
|
||||
btrfs_set_path_blocking(p);
|
||||
|
||||
if (tmp)
|
||||
free_extent_buffer(tmp);
|
||||
if (p->reada)
|
||||
reada_for_search(root, p, level, slot, key->objectid);
|
||||
|
||||
btrfs_release_path(NULL, p);
|
||||
tmp = read_tree_block(root, blocknr, blocksize, gen);
|
||||
if (tmp)
|
||||
free_extent_buffer(tmp);
|
||||
|
Loading…
Reference in New Issue
Block a user