Commit f4468e94 authored by Chris Mason's avatar Chris Mason Committed by David Woodhouse

Btrfs: Let some locks go during defrag and snapshot dropping

Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 37fa7046
...@@ -300,9 +300,9 @@ struct btrfs_fs_info { ...@@ -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;
......
...@@ -1018,7 +1018,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root ...@@ -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, ...@@ -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 ...@@ -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;
......
...@@ -354,6 +354,7 @@ int btrfs_defrag_dirty_roots(struct btrfs_fs_info *info) ...@@ -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, ...@@ -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, ...@@ -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;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment