diff options
Diffstat (limited to 'fs/btrfs')
| -rw-r--r-- | fs/btrfs/ctree.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index e5b2533b691..a99f1c2a710 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
| @@ -1325,12 +1325,12 @@ static noinline int reada_for_balance(struct btrfs_root *root, | |||
| 1325 | int ret = 0; | 1325 | int ret = 0; |
| 1326 | int blocksize; | 1326 | int blocksize; |
| 1327 | 1327 | ||
| 1328 | parent = path->nodes[level - 1]; | 1328 | parent = path->nodes[level + 1]; |
| 1329 | if (!parent) | 1329 | if (!parent) |
| 1330 | return 0; | 1330 | return 0; |
| 1331 | 1331 | ||
| 1332 | nritems = btrfs_header_nritems(parent); | 1332 | nritems = btrfs_header_nritems(parent); |
| 1333 | slot = path->slots[level]; | 1333 | slot = path->slots[level + 1]; |
| 1334 | blocksize = btrfs_level_size(root, level); | 1334 | blocksize = btrfs_level_size(root, level); |
| 1335 | 1335 | ||
| 1336 | if (slot > 0) { | 1336 | if (slot > 0) { |
| @@ -1341,7 +1341,7 @@ static noinline int reada_for_balance(struct btrfs_root *root, | |||
| 1341 | block1 = 0; | 1341 | block1 = 0; |
| 1342 | free_extent_buffer(eb); | 1342 | free_extent_buffer(eb); |
| 1343 | } | 1343 | } |
| 1344 | if (slot < nritems) { | 1344 | if (slot + 1 < nritems) { |
| 1345 | block2 = btrfs_node_blockptr(parent, slot + 1); | 1345 | block2 = btrfs_node_blockptr(parent, slot + 1); |
| 1346 | gen = btrfs_node_ptr_generation(parent, slot + 1); | 1346 | gen = btrfs_node_ptr_generation(parent, slot + 1); |
| 1347 | eb = btrfs_find_tree_block(root, block2, blocksize); | 1347 | eb = btrfs_find_tree_block(root, block2, blocksize); |
| @@ -1351,7 +1351,11 @@ static noinline int reada_for_balance(struct btrfs_root *root, | |||
| 1351 | } | 1351 | } |
| 1352 | if (block1 || block2) { | 1352 | if (block1 || block2) { |
| 1353 | ret = -EAGAIN; | 1353 | ret = -EAGAIN; |
| 1354 | |||
| 1355 | /* release the whole path */ | ||
| 1354 | btrfs_release_path(root, path); | 1356 | btrfs_release_path(root, path); |
| 1357 | |||
| 1358 | /* read the blocks */ | ||
| 1355 | if (block1) | 1359 | if (block1) |
| 1356 | readahead_tree_block(root, block1, blocksize, 0); | 1360 | readahead_tree_block(root, block1, blocksize, 0); |
| 1357 | if (block2) | 1361 | if (block2) |
| @@ -1361,7 +1365,7 @@ static noinline int reada_for_balance(struct btrfs_root *root, | |||
| 1361 | eb = read_tree_block(root, block1, blocksize, 0); | 1365 | eb = read_tree_block(root, block1, blocksize, 0); |
| 1362 | free_extent_buffer(eb); | 1366 | free_extent_buffer(eb); |
| 1363 | } | 1367 | } |
| 1364 | if (block1) { | 1368 | if (block2) { |
| 1365 | eb = read_tree_block(root, block2, blocksize, 0); | 1369 | eb = read_tree_block(root, block2, blocksize, 0); |
| 1366 | free_extent_buffer(eb); | 1370 | free_extent_buffer(eb); |
| 1367 | } | 1371 | } |
| @@ -1481,12 +1485,15 @@ read_block_for_search(struct btrfs_trans_handle *trans, | |||
| 1481 | * of the btree by dropping locks before | 1485 | * of the btree by dropping locks before |
| 1482 | * we read. | 1486 | * we read. |
| 1483 | */ | 1487 | */ |
| 1484 | btrfs_release_path(NULL, p); | 1488 | btrfs_unlock_up_safe(p, level + 1); |
| 1489 | btrfs_set_path_blocking(p); | ||
| 1490 | |||
| 1485 | if (tmp) | 1491 | if (tmp) |
| 1486 | free_extent_buffer(tmp); | 1492 | free_extent_buffer(tmp); |
| 1487 | if (p->reada) | 1493 | if (p->reada) |
| 1488 | reada_for_search(root, p, level, slot, key->objectid); | 1494 | reada_for_search(root, p, level, slot, key->objectid); |
| 1489 | 1495 | ||
| 1496 | btrfs_release_path(NULL, p); | ||
| 1490 | tmp = read_tree_block(root, blocknr, blocksize, gen); | 1497 | tmp = read_tree_block(root, blocknr, blocksize, gen); |
| 1491 | if (tmp) | 1498 | if (tmp) |
| 1492 | free_extent_buffer(tmp); | 1499 | free_extent_buffer(tmp); |
