Btrfs: Only prep for btree deletion balances when nodes are mostly empty
authorChris Mason <chris.mason@oracle.com>
Wed, 4 Feb 2009 14:12:46 +0000 (09:12 -0500)
committerChris Mason <chris.mason@oracle.com>
Wed, 4 Feb 2009 14:12:46 +0000 (09:12 -0500)
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>
fs/btrfs/ctree.c

index 0d1e3b9..551177c 100644 (file)
@@ -1518,18 +1518,19 @@ again:
                         */
                        if (prealloc_block.objectid &&
                            prealloc_block.offset != b->len) {
-                               btrfs_set_path_blocking(p);
+                               btrfs_release_path(root, p);
                                btrfs_free_reserved_extent(root,
                                           prealloc_block.objectid,
                                           prealloc_block.offset);
                                prealloc_block.objectid = 0;
+                               goto again;
                        }
 
                        /*
                         * for higher level blocks, try not to allocate blocks
                         * with the block and the parent locks held.
                         */
-                       if (level > 1 && !prealloc_block.objectid &&
+                       if (level > 0 && !prealloc_block.objectid &&
                            btrfs_path_lock_waiting(p, level)) {
                                u32 size = b->len;
                                u64 hint = b->start;
@@ -1614,7 +1615,9 @@ cow_done:
                                }
                                b = p->nodes[level];
                                slot = p->slots[level];
-                       } else if (ins_len < 0) {
+                       } else if (ins_len < 0 &&
+                                  btrfs_header_nritems(b) <
+                                  BTRFS_NODEPTRS_PER_BLOCK(root) / 4) {
                                int sret;
 
                                sret = reada_for_balance(root, p, level);