aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2009-02-04 09:12:46 -0500
committerChris Mason <chris.mason@oracle.com>2009-02-04 09:12:46 -0500
commit7b78c170dc4f538cc7ee66f47b3aac3f3974a36c (patch)
treee2301fba4de0f3a04cf4b691f63e2bdf1e8c64d2
parent12f4daccfc3732280debba8f9ba49720372de831 (diff)
Btrfs: Only prep for btree deletion balances when nodes are mostly empty
Whenever an item deletion is done, we need to balance all the nodes in the tree to make sure we don't end up with an empty node if a pointer is deleted. This balance prep happens from the root of the tree down so we can drop our locks as we go. reada_for_balance was triggering read-ahead on neighboring nodes even when no balancing was required. This adds an extra check to avoid calling balance_level() and avoid reada_for_balance() when a balance won't be required. Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/ctree.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 0d1e3b91e7bd..551177c0011a 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1518,18 +1518,19 @@ again:
1518 */ 1518 */
1519 if (prealloc_block.objectid && 1519 if (prealloc_block.objectid &&
1520 prealloc_block.offset != b->len) { 1520 prealloc_block.offset != b->len) {
1521 btrfs_set_path_blocking(p); 1521 btrfs_release_path(root, p);
1522 btrfs_free_reserved_extent(root, 1522 btrfs_free_reserved_extent(root,
1523 prealloc_block.objectid, 1523 prealloc_block.objectid,
1524 prealloc_block.offset); 1524 prealloc_block.offset);
1525 prealloc_block.objectid = 0; 1525 prealloc_block.objectid = 0;
1526 goto again;
1526 } 1527 }
1527 1528
1528 /* 1529 /*
1529 * for higher level blocks, try not to allocate blocks 1530 * for higher level blocks, try not to allocate blocks
1530 * with the block and the parent locks held. 1531 * with the block and the parent locks held.
1531 */ 1532 */
1532 if (level > 1 && !prealloc_block.objectid && 1533 if (level > 0 && !prealloc_block.objectid &&
1533 btrfs_path_lock_waiting(p, level)) { 1534 btrfs_path_lock_waiting(p, level)) {
1534 u32 size = b->len; 1535 u32 size = b->len;
1535 u64 hint = b->start; 1536 u64 hint = b->start;
@@ -1614,7 +1615,9 @@ cow_done:
1614 } 1615 }
1615 b = p->nodes[level]; 1616 b = p->nodes[level];
1616 slot = p->slots[level]; 1617 slot = p->slots[level];
1617 } else if (ins_len < 0) { 1618 } else if (ins_len < 0 &&
1619 btrfs_header_nritems(b) <
1620 BTRFS_NODEPTRS_PER_BLOCK(root) / 4) {
1618 int sret; 1621 int sret;
1619 1622
1620 sret = reada_for_balance(root, p, level); 1623 sret = reada_for_balance(root, p, level);