Btrfs: Let some locks go during defrag and snapshot dropping
authorChris Mason <chris.mason@oracle.com>
Wed, 8 Aug 2007 14:08:58 +0000 (10:08 -0400)
committerDavid Woodhouse <dwmw2@hera.kernel.org>
Wed, 8 Aug 2007 14:08:58 +0000 (10:08 -0400)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
fs/btrfs/ctree.h
fs/btrfs/extent-tree.c
fs/btrfs/transaction.c

index 42aa20301bc9b27e571413788cd6fc5d4ef5b469..8b7d01597f4fdd57b0d3065aa66945f434787811 100644 (file)
@@ -300,9 +300,9 @@ struct btrfs_fs_info {
        struct radix_tree_root block_group_data_radix;
        struct radix_tree_root extent_map_radix;
 
-       u64 extent_tree_insert[BTRFS_MAX_LEVEL * 3];
+       u64 extent_tree_insert[BTRFS_MAX_LEVEL * 6];
        int extent_tree_insert_nr;
-       u64 extent_tree_prealloc[BTRFS_MAX_LEVEL * 3];
+       u64 extent_tree_prealloc[BTRFS_MAX_LEVEL * 6];
        int extent_tree_prealloc_nr;
 
        u64 generation;
index 26b8d340649128d232ab3ba41e7a2f76a0905a79..f7d76d34fc3752a22d26761d4b8f487c8166d6b4 100644 (file)
@@ -1018,7 +1018,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
        if (num_blocks == 0) {
                fill_prealloc = 1;
                num_blocks = 1;
-               total_needed = (min(level + 1, BTRFS_MAX_LEVEL) + 2) * 3;
+               total_needed = (min(level + 1, BTRFS_MAX_LEVEL)) * 6;
        }
        if (fill_prealloc) {
                u64 first;
@@ -1300,6 +1300,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
                        ins->objectid;
                ret = update_block_group(trans, root,
                                         ins->objectid, ins->offset, 1, 0, 0);
+               WARN_ON(info->extent_tree_insert_nr >
+                       ARRAY_SIZE(info->extent_tree_insert));
                BUG_ON(ret);
                return 0;
        }
@@ -1628,7 +1630,7 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
                if (wret < 0)
                        ret = wret;
                num_walks++;
-               if (num_walks > 10) {
+               if (num_walks > 2) {
                        ret = -EAGAIN;
                        get_bh(root->node);
                        break;
index 338a7199363b12875868414a7336c1f25bd7449d..88b0752550b63d0a84cebc2580cce4340f6b9c16 100644 (file)
@@ -354,6 +354,7 @@ int btrfs_defrag_dirty_roots(struct btrfs_fs_info *info)
                                mutex_unlock(&info->fs_mutex);
 
                                btrfs_btree_balance_dirty(root);
+                               cond_resched();
 
                                mutex_lock(&info->fs_mutex);
                                trans = btrfs_start_transaction(tree_root, 1);
@@ -394,6 +395,12 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
                                ret = err;
                        ret = btrfs_end_transaction(trans, tree_root);
                        BUG_ON(ret);
+                       mutex_unlock(&tree_root->fs_info->fs_mutex);
+
+                       btrfs_btree_balance_dirty(tree_root);
+                       schedule();
+
+                       mutex_lock(&tree_root->fs_info->fs_mutex);
                }
                BUG_ON(ret);
                ret = btrfs_del_root(trans, tree_root, &dirty->root->root_key);
@@ -406,6 +413,7 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
                kfree(dirty);
                mutex_unlock(&tree_root->fs_info->fs_mutex);
                btrfs_btree_balance_dirty(tree_root);
+               schedule();
        }
        return ret;
 }