diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-06-19 16:23:05 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-06-19 16:23:05 -0400 |
commit | e011599b0f375683499bf1a9954703f4959a8d00 (patch) | |
tree | 347afa66c1a9ea5ad1bb5c76e522f0f29a9db513 /fs | |
parent | 85e55b13e4e318672f669747e5e010d1b707b198 (diff) |
Btrfs: reada while dropping snapshots
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 47e91184fff3..b38c3e92f0c8 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -940,7 +940,6 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
940 | int wrapped = 0; | 940 | int wrapped = 0; |
941 | u64 limit; | 941 | u64 limit; |
942 | 942 | ||
943 | path = btrfs_alloc_path(); | ||
944 | ins->flags = 0; | 943 | ins->flags = 0; |
945 | btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); | 944 | btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); |
946 | 945 | ||
@@ -974,6 +973,8 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
974 | data, 1); | 973 | data, 1); |
975 | } | 974 | } |
976 | 975 | ||
976 | path = btrfs_alloc_path(); | ||
977 | |||
977 | check_failed: | 978 | check_failed: |
978 | if (!block_group->data) | 979 | if (!block_group->data) |
979 | search_start = find_search_start(root, &block_group, | 980 | search_start = find_search_start(root, &block_group, |
@@ -1355,6 +1356,28 @@ static int drop_leaf_ref(struct btrfs_trans_handle *trans, | |||
1355 | return 0; | 1356 | return 0; |
1356 | } | 1357 | } |
1357 | 1358 | ||
1359 | static void reada_walk_down(struct btrfs_root *root, | ||
1360 | struct btrfs_node *node) | ||
1361 | { | ||
1362 | int i; | ||
1363 | u32 nritems; | ||
1364 | u64 blocknr; | ||
1365 | int ret; | ||
1366 | u32 refs; | ||
1367 | |||
1368 | nritems = btrfs_header_nritems(&node->header); | ||
1369 | for (i = 0; i < nritems; i++) { | ||
1370 | blocknr = btrfs_node_blockptr(node, i); | ||
1371 | ret = lookup_extent_ref(NULL, root, blocknr, 1, &refs); | ||
1372 | BUG_ON(ret); | ||
1373 | if (refs != 1) | ||
1374 | continue; | ||
1375 | ret = readahead_tree_block(root, blocknr); | ||
1376 | if (ret) | ||
1377 | break; | ||
1378 | } | ||
1379 | } | ||
1380 | |||
1358 | /* | 1381 | /* |
1359 | * helper function for drop_snapshot, this walks down the tree dropping ref | 1382 | * helper function for drop_snapshot, this walks down the tree dropping ref |
1360 | * counts as it goes. | 1383 | * counts as it goes. |
@@ -1375,6 +1398,7 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1375 | BUG_ON(ret); | 1398 | BUG_ON(ret); |
1376 | if (refs > 1) | 1399 | if (refs > 1) |
1377 | goto out; | 1400 | goto out; |
1401 | |||
1378 | /* | 1402 | /* |
1379 | * walk down to the last node level and free all the leaves | 1403 | * walk down to the last node level and free all the leaves |
1380 | */ | 1404 | */ |
@@ -1382,8 +1406,13 @@ static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1382 | WARN_ON(*level < 0); | 1406 | WARN_ON(*level < 0); |
1383 | WARN_ON(*level >= BTRFS_MAX_LEVEL); | 1407 | WARN_ON(*level >= BTRFS_MAX_LEVEL); |
1384 | cur = path->nodes[*level]; | 1408 | cur = path->nodes[*level]; |
1409 | |||
1410 | if (*level > 0 && path->slots[*level] == 0) | ||
1411 | reada_walk_down(root, btrfs_buffer_node(cur)); | ||
1412 | |||
1385 | if (btrfs_header_level(btrfs_buffer_header(cur)) != *level) | 1413 | if (btrfs_header_level(btrfs_buffer_header(cur)) != *level) |
1386 | WARN_ON(1); | 1414 | WARN_ON(1); |
1415 | |||
1387 | if (path->slots[*level] >= | 1416 | if (path->slots[*level] >= |
1388 | btrfs_header_nritems(btrfs_buffer_header(cur))) | 1417 | btrfs_header_nritems(btrfs_buffer_header(cur))) |
1389 | break; | 1418 | break; |