aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-06-19 16:23:05 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-06-19 16:23:05 -0400
commite011599b0f375683499bf1a9954703f4959a8d00 (patch)
tree347afa66c1a9ea5ad1bb5c76e522f0f29a9db513 /fs
parent85e55b13e4e318672f669747e5e010d1b707b198 (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.c31
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
977check_failed: 978check_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
1359static 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;