diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-06-25 16:01:30 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:03 -0400 |
commit | a213501153fd66e2359e091b1612841305ba6551 (patch) | |
tree | 1f4c316c9d3cad0eb6d9be14cb0e67e46e815dce /fs/btrfs/extent-tree.c | |
parent | 925baeddc5b0764a53f2214a1253251bab0e0324 (diff) |
Btrfs: Replace the big fs_mutex with a collection of other locks
Extent alloctions are still protected by a large alloc_mutex.
Objectid allocations are covered by a objectid mutex
Other btree operations are protected by a lock on individual btree nodes
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 18 |
1 files changed, 7 insertions, 11 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 7e40c516fe62..890b9e9d8e27 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -1577,9 +1577,11 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1577 | } | 1577 | } |
1578 | 1578 | ||
1579 | /* block accounting for super block */ | 1579 | /* block accounting for super block */ |
1580 | spin_lock_irq(&info->delalloc_lock); | ||
1580 | super_used = btrfs_super_bytes_used(&info->super_copy); | 1581 | super_used = btrfs_super_bytes_used(&info->super_copy); |
1581 | btrfs_set_super_bytes_used(&info->super_copy, | 1582 | btrfs_set_super_bytes_used(&info->super_copy, |
1582 | super_used - num_bytes); | 1583 | super_used - num_bytes); |
1584 | spin_unlock_irq(&info->delalloc_lock); | ||
1583 | 1585 | ||
1584 | /* block accounting for root item */ | 1586 | /* block accounting for root item */ |
1585 | root_used = btrfs_root_used(&root->root_item); | 1587 | root_used = btrfs_root_used(&root->root_item); |
@@ -1968,8 +1970,10 @@ again: | |||
1968 | } | 1970 | } |
1969 | 1971 | ||
1970 | /* block accounting for super block */ | 1972 | /* block accounting for super block */ |
1973 | spin_lock_irq(&info->delalloc_lock); | ||
1971 | super_used = btrfs_super_bytes_used(&info->super_copy); | 1974 | super_used = btrfs_super_bytes_used(&info->super_copy); |
1972 | btrfs_set_super_bytes_used(&info->super_copy, super_used + num_bytes); | 1975 | btrfs_set_super_bytes_used(&info->super_copy, super_used + num_bytes); |
1976 | spin_unlock_irq(&info->delalloc_lock); | ||
1973 | 1977 | ||
1974 | /* block accounting for root item */ | 1978 | /* block accounting for root item */ |
1975 | root_used = btrfs_root_used(&root->root_item); | 1979 | root_used = btrfs_root_used(&root->root_item); |
@@ -2172,12 +2176,12 @@ static void noinline reada_walk_down(struct btrfs_root *root, | |||
2172 | continue; | 2176 | continue; |
2173 | } | 2177 | } |
2174 | } | 2178 | } |
2175 | mutex_unlock(&root->fs_info->fs_mutex); | 2179 | mutex_unlock(&root->fs_info->alloc_mutex); |
2176 | ret = readahead_tree_block(root, bytenr, blocksize, | 2180 | ret = readahead_tree_block(root, bytenr, blocksize, |
2177 | btrfs_node_ptr_generation(node, i)); | 2181 | btrfs_node_ptr_generation(node, i)); |
2178 | last = bytenr + blocksize; | 2182 | last = bytenr + blocksize; |
2179 | cond_resched(); | 2183 | cond_resched(); |
2180 | mutex_lock(&root->fs_info->fs_mutex); | 2184 | mutex_lock(&root->fs_info->alloc_mutex); |
2181 | if (ret) | 2185 | if (ret) |
2182 | break; | 2186 | break; |
2183 | } | 2187 | } |
@@ -2254,11 +2258,9 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, | |||
2254 | free_extent_buffer(next); | 2258 | free_extent_buffer(next); |
2255 | reada_walk_down(root, cur, path->slots[*level]); | 2259 | reada_walk_down(root, cur, path->slots[*level]); |
2256 | 2260 | ||
2257 | mutex_unlock(&root->fs_info->fs_mutex); | ||
2258 | mutex_unlock(&root->fs_info->alloc_mutex); | 2261 | mutex_unlock(&root->fs_info->alloc_mutex); |
2259 | next = read_tree_block(root, bytenr, blocksize, | 2262 | next = read_tree_block(root, bytenr, blocksize, |
2260 | ptr_gen); | 2263 | ptr_gen); |
2261 | mutex_lock(&root->fs_info->fs_mutex); | ||
2262 | mutex_lock(&root->fs_info->alloc_mutex); | 2264 | mutex_lock(&root->fs_info->alloc_mutex); |
2263 | 2265 | ||
2264 | /* we've dropped the lock, double check */ | 2266 | /* we've dropped the lock, double check */ |
@@ -2381,6 +2383,7 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root | |||
2381 | int orig_level; | 2383 | int orig_level; |
2382 | struct btrfs_root_item *root_item = &root->root_item; | 2384 | struct btrfs_root_item *root_item = &root->root_item; |
2383 | 2385 | ||
2386 | WARN_ON(!mutex_is_locked(&root->fs_info->drop_mutex)); | ||
2384 | path = btrfs_alloc_path(); | 2387 | path = btrfs_alloc_path(); |
2385 | BUG_ON(!path); | 2388 | BUG_ON(!path); |
2386 | 2389 | ||
@@ -2710,7 +2713,6 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root, | |||
2710 | *last_file_root == ref_root) | 2713 | *last_file_root == ref_root) |
2711 | goto out; | 2714 | goto out; |
2712 | 2715 | ||
2713 | mutex_unlock(&extent_root->fs_info->fs_mutex); | ||
2714 | inode = btrfs_iget_locked(extent_root->fs_info->sb, | 2716 | inode = btrfs_iget_locked(extent_root->fs_info->sb, |
2715 | ref_objectid, found_root); | 2717 | ref_objectid, found_root); |
2716 | if (inode->i_state & I_NEW) { | 2718 | if (inode->i_state & I_NEW) { |
@@ -2727,7 +2729,6 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root, | |||
2727 | * the latest version of the tree root | 2729 | * the latest version of the tree root |
2728 | */ | 2730 | */ |
2729 | if (is_bad_inode(inode)) { | 2731 | if (is_bad_inode(inode)) { |
2730 | mutex_lock(&extent_root->fs_info->fs_mutex); | ||
2731 | goto out; | 2732 | goto out; |
2732 | } | 2733 | } |
2733 | *last_file_objectid = inode->i_ino; | 2734 | *last_file_objectid = inode->i_ino; |
@@ -2736,7 +2737,6 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root, | |||
2736 | 2737 | ||
2737 | relocate_inode_pages(inode, ref_offset, extent_key->offset); | 2738 | relocate_inode_pages(inode, ref_offset, extent_key->offset); |
2738 | iput(inode); | 2739 | iput(inode); |
2739 | mutex_lock(&extent_root->fs_info->fs_mutex); | ||
2740 | } else { | 2740 | } else { |
2741 | struct btrfs_trans_handle *trans; | 2741 | struct btrfs_trans_handle *trans; |
2742 | struct extent_buffer *eb; | 2742 | struct extent_buffer *eb; |
@@ -3033,9 +3033,7 @@ next: | |||
3033 | 3033 | ||
3034 | if (progress && need_resched()) { | 3034 | if (progress && need_resched()) { |
3035 | memcpy(&key, &found_key, sizeof(key)); | 3035 | memcpy(&key, &found_key, sizeof(key)); |
3036 | mutex_unlock(&root->fs_info->fs_mutex); | ||
3037 | cond_resched(); | 3036 | cond_resched(); |
3038 | mutex_lock(&root->fs_info->fs_mutex); | ||
3039 | btrfs_release_path(root, path); | 3037 | btrfs_release_path(root, path); |
3040 | btrfs_search_slot(NULL, root, &key, path, 0, 0); | 3038 | btrfs_search_slot(NULL, root, &key, path, 0, 0); |
3041 | progress = 0; | 3039 | progress = 0; |
@@ -3068,9 +3066,7 @@ next: | |||
3068 | trans = btrfs_start_transaction(tree_root, 1); | 3066 | trans = btrfs_start_transaction(tree_root, 1); |
3069 | btrfs_commit_transaction(trans, tree_root); | 3067 | btrfs_commit_transaction(trans, tree_root); |
3070 | 3068 | ||
3071 | mutex_unlock(&root->fs_info->fs_mutex); | ||
3072 | btrfs_clean_old_snapshots(tree_root); | 3069 | btrfs_clean_old_snapshots(tree_root); |
3073 | mutex_lock(&root->fs_info->fs_mutex); | ||
3074 | 3070 | ||
3075 | trans = btrfs_start_transaction(tree_root, 1); | 3071 | trans = btrfs_start_transaction(tree_root, 1); |
3076 | btrfs_commit_transaction(trans, tree_root); | 3072 | btrfs_commit_transaction(trans, tree_root); |