Browse Source

Btrfs: Let some locks go during defrag and snapshot dropping

Signed-off-by: Chris Mason <chris.mason@oracle.com>
Chris Mason 18 years ago
parent
commit
f4468e94c8
3 changed files with 14 additions and 4 deletions
  1. 2 2
      fs/btrfs/ctree.h
  2. 4 2
      fs/btrfs/extent-tree.c
  3. 8 0
      fs/btrfs/transaction.c

+ 2 - 2
fs/btrfs/ctree.h

@@ -300,9 +300,9 @@ struct btrfs_fs_info {
 	struct radix_tree_root block_group_data_radix;
 	struct radix_tree_root block_group_data_radix;
 	struct radix_tree_root extent_map_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;
 	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;
 	int extent_tree_prealloc_nr;
 
 
 	u64 generation;
 	u64 generation;

+ 4 - 2
fs/btrfs/extent-tree.c

@@ -1018,7 +1018,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
 	if (num_blocks == 0) {
 	if (num_blocks == 0) {
 		fill_prealloc = 1;
 		fill_prealloc = 1;
 		num_blocks = 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) {
 	if (fill_prealloc) {
 		u64 first;
 		u64 first;
@@ -1300,6 +1300,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
 			ins->objectid;
 			ins->objectid;
 		ret = update_block_group(trans, root,
 		ret = update_block_group(trans, root,
 					 ins->objectid, ins->offset, 1, 0, 0);
 					 ins->objectid, ins->offset, 1, 0, 0);
+		WARN_ON(info->extent_tree_insert_nr >
+			ARRAY_SIZE(info->extent_tree_insert));
 		BUG_ON(ret);
 		BUG_ON(ret);
 		return 0;
 		return 0;
 	}
 	}
@@ -1628,7 +1630,7 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
 		if (wret < 0)
 		if (wret < 0)
 			ret = wret;
 			ret = wret;
 		num_walks++;
 		num_walks++;
-		if (num_walks > 10) {
+		if (num_walks > 2) {
 			ret = -EAGAIN;
 			ret = -EAGAIN;
 			get_bh(root->node);
 			get_bh(root->node);
 			break;
 			break;

+ 8 - 0
fs/btrfs/transaction.c

@@ -354,6 +354,7 @@ int btrfs_defrag_dirty_roots(struct btrfs_fs_info *info)
 				mutex_unlock(&info->fs_mutex);
 				mutex_unlock(&info->fs_mutex);
 
 
 				btrfs_btree_balance_dirty(root);
 				btrfs_btree_balance_dirty(root);
+				cond_resched();
 
 
 				mutex_lock(&info->fs_mutex);
 				mutex_lock(&info->fs_mutex);
 				trans = btrfs_start_transaction(tree_root, 1);
 				trans = btrfs_start_transaction(tree_root, 1);
@@ -394,6 +395,12 @@ static int drop_dirty_roots(struct btrfs_root *tree_root,
 				ret = err;
 				ret = err;
 			ret = btrfs_end_transaction(trans, tree_root);
 			ret = btrfs_end_transaction(trans, tree_root);
 			BUG_ON(ret);
 			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);
 		BUG_ON(ret);
 		ret = btrfs_del_root(trans, tree_root, &dirty->root->root_key);
 		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);
 		kfree(dirty);
 		mutex_unlock(&tree_root->fs_info->fs_mutex);
 		mutex_unlock(&tree_root->fs_info->fs_mutex);
 		btrfs_btree_balance_dirty(tree_root);
 		btrfs_btree_balance_dirty(tree_root);
+		schedule();
 	}
 	}
 	return ret;
 	return ret;
 }
 }