aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-07-08 14:19:17 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:04 -0400
commit7d9eb12c8739e7dc80c78c6b3596f912ecd8f941 (patch)
tree000608285b44920f22e0888753b36299bc762cef /fs/btrfs/extent-tree.c
parenta7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0 (diff)
Btrfs: Add locking around volume management (device add/remove/balance)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c73
1 files changed, 55 insertions, 18 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 5e0857ffbc35..8ebfa6be0790 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -245,6 +245,7 @@ static int noinline find_search_start(struct btrfs_root *root,
245 u64 search_start = *start_ret; 245 u64 search_start = *start_ret;
246 int wrapped = 0; 246 int wrapped = 0;
247 247
248 WARN_ON(!mutex_is_locked(&root->fs_info->alloc_mutex));
248 total_fs_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy); 249 total_fs_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
249 free_space_cache = &root->fs_info->free_space_cache; 250 free_space_cache = &root->fs_info->free_space_cache;
250 251
@@ -1242,6 +1243,7 @@ static int update_block_group(struct btrfs_trans_handle *trans,
1242 u64 start; 1243 u64 start;
1243 u64 end; 1244 u64 end;
1244 1245
1246 WARN_ON(!mutex_is_locked(&root->fs_info->alloc_mutex));
1245 while(total) { 1247 while(total) {
1246 cache = btrfs_lookup_block_group(info, bytenr); 1248 cache = btrfs_lookup_block_group(info, bytenr);
1247 if (!cache) { 1249 if (!cache) {
@@ -1297,6 +1299,7 @@ static int update_pinned_extents(struct btrfs_root *root,
1297 struct btrfs_block_group_cache *cache; 1299 struct btrfs_block_group_cache *cache;
1298 struct btrfs_fs_info *fs_info = root->fs_info; 1300 struct btrfs_fs_info *fs_info = root->fs_info;
1299 1301
1302 WARN_ON(!mutex_is_locked(&root->fs_info->alloc_mutex));
1300 if (pin) { 1303 if (pin) {
1301 set_extent_dirty(&fs_info->pinned_extents, 1304 set_extent_dirty(&fs_info->pinned_extents,
1302 bytenr, bytenr + num - 1, GFP_NOFS); 1305 bytenr, bytenr + num - 1, GFP_NOFS);
@@ -1391,6 +1394,7 @@ static int finish_current_insert(struct btrfs_trans_handle *trans,
1391 int level; 1394 int level;
1392 int err = 0; 1395 int err = 0;
1393 1396
1397 WARN_ON(!mutex_is_locked(&extent_root->fs_info->alloc_mutex));
1394 btrfs_set_stack_extent_refs(&extent_item, 1); 1398 btrfs_set_stack_extent_refs(&extent_item, 1);
1395 btrfs_set_key_type(&ins, BTRFS_EXTENT_ITEM_KEY); 1399 btrfs_set_key_type(&ins, BTRFS_EXTENT_ITEM_KEY);
1396 path = btrfs_alloc_path(); 1400 path = btrfs_alloc_path();
@@ -1437,6 +1441,7 @@ static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes,
1437{ 1441{
1438 int err = 0; 1442 int err = 0;
1439 1443
1444 WARN_ON(!mutex_is_locked(&root->fs_info->alloc_mutex));
1440 if (!pending) { 1445 if (!pending) {
1441 struct extent_buffer *buf; 1446 struct extent_buffer *buf;
1442 buf = btrfs_find_tree_block(root, bytenr, num_bytes); 1447 buf = btrfs_find_tree_block(root, bytenr, num_bytes);
@@ -1490,6 +1495,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
1490 struct btrfs_extent_item *ei; 1495 struct btrfs_extent_item *ei;
1491 u32 refs; 1496 u32 refs;
1492 1497
1498 WARN_ON(!mutex_is_locked(&root->fs_info->alloc_mutex));
1493 key.objectid = bytenr; 1499 key.objectid = bytenr;
1494 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 1500 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
1495 key.offset = num_bytes; 1501 key.offset = num_bytes;
@@ -1619,6 +1625,7 @@ static int del_pending_extents(struct btrfs_trans_handle *trans, struct
1619 struct extent_io_tree *pending_del; 1625 struct extent_io_tree *pending_del;
1620 struct extent_io_tree *pinned_extents; 1626 struct extent_io_tree *pinned_extents;
1621 1627
1628 WARN_ON(!mutex_is_locked(&extent_root->fs_info->alloc_mutex));
1622 pending_del = &extent_root->fs_info->pending_del; 1629 pending_del = &extent_root->fs_info->pending_del;
1623 pinned_extents = &extent_root->fs_info->pinned_extents; 1630 pinned_extents = &extent_root->fs_info->pinned_extents;
1624 1631
@@ -2428,6 +2435,10 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root
2428 btrfs_node_key(node, &found_key, path->slots[level]); 2435 btrfs_node_key(node, &found_key, path->slots[level]);
2429 WARN_ON(memcmp(&found_key, &root_item->drop_progress, 2436 WARN_ON(memcmp(&found_key, &root_item->drop_progress,
2430 sizeof(found_key))); 2437 sizeof(found_key)));
2438 /*
2439 * unlock our path, this is safe because only this
2440 * function is allowed to delete this snapshot
2441 */
2431 for (i = 0; i < BTRFS_MAX_LEVEL; i++) { 2442 for (i = 0; i < BTRFS_MAX_LEVEL; i++) {
2432 if (path->nodes[i] && path->locks[i]) { 2443 if (path->nodes[i] && path->locks[i]) {
2433 path->locks[i] = 0; 2444 path->locks[i] = 0;
@@ -2611,7 +2622,6 @@ static int find_root_for_ref(struct btrfs_root *root,
2611 u64 root_search_start = BTRFS_FS_TREE_OBJECTID; 2622 u64 root_search_start = BTRFS_FS_TREE_OBJECTID;
2612 u64 found_bytenr; 2623 u64 found_bytenr;
2613 int ret; 2624 int ret;
2614 int i;
2615 2625
2616 root_location.offset = (u64)-1; 2626 root_location.offset = (u64)-1;
2617 root_location.type = BTRFS_ROOT_ITEM_KEY; 2627 root_location.type = BTRFS_ROOT_ITEM_KEY;
@@ -2635,12 +2645,6 @@ static int find_root_for_ref(struct btrfs_root *root,
2635 found_bytenr = path->nodes[level]->start; 2645 found_bytenr = path->nodes[level]->start;
2636 } 2646 }
2637 2647
2638 for (i = level; i < BTRFS_MAX_LEVEL; i++) {
2639 if (!path->nodes[i])
2640 break;
2641 free_extent_buffer(path->nodes[i]);
2642 path->nodes[i] = NULL;
2643 }
2644 btrfs_release_path(cur_root, path); 2648 btrfs_release_path(cur_root, path);
2645 2649
2646 if (found_bytenr == bytenr) { 2650 if (found_bytenr == bytenr) {
@@ -2689,6 +2693,8 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
2689 int ret; 2693 int ret;
2690 int level; 2694 int level;
2691 2695
2696 WARN_ON(!mutex_is_locked(&extent_root->fs_info->alloc_mutex));
2697
2692 ref = btrfs_item_ptr(path->nodes[0], path->slots[0], 2698 ref = btrfs_item_ptr(path->nodes[0], path->slots[0],
2693 struct btrfs_extent_ref); 2699 struct btrfs_extent_ref);
2694 ref_root = btrfs_ref_root(path->nodes[0], ref); 2700 ref_root = btrfs_ref_root(path->nodes[0], ref);
@@ -2707,6 +2713,7 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
2707 found_root = btrfs_read_fs_root_no_name(extent_root->fs_info, 2713 found_root = btrfs_read_fs_root_no_name(extent_root->fs_info,
2708 &root_location); 2714 &root_location);
2709 BUG_ON(!found_root); 2715 BUG_ON(!found_root);
2716 mutex_unlock(&extent_root->fs_info->alloc_mutex);
2710 2717
2711 if (ref_objectid >= BTRFS_FIRST_FREE_OBJECTID) { 2718 if (ref_objectid >= BTRFS_FIRST_FREE_OBJECTID) {
2712 found_key.objectid = ref_objectid; 2719 found_key.objectid = ref_objectid;
@@ -2748,9 +2755,9 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
2748 /* this can happen if the reference is not against 2755 /* this can happen if the reference is not against
2749 * the latest version of the tree root 2756 * the latest version of the tree root
2750 */ 2757 */
2751 if (is_bad_inode(inode)) { 2758 if (is_bad_inode(inode))
2752 goto out; 2759 goto out;
2753 } 2760
2754 *last_file_objectid = inode->i_ino; 2761 *last_file_objectid = inode->i_ino;
2755 *last_file_root = found_root->root_key.objectid; 2762 *last_file_root = found_root->root_key.objectid;
2756 *last_file_offset = ref_offset; 2763 *last_file_offset = ref_offset;
@@ -2760,7 +2767,7 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
2760 } else { 2767 } else {
2761 struct btrfs_trans_handle *trans; 2768 struct btrfs_trans_handle *trans;
2762 struct extent_buffer *eb; 2769 struct extent_buffer *eb;
2763 int i; 2770 int needs_lock = 0;
2764 2771
2765 eb = read_tree_block(found_root, extent_key->objectid, 2772 eb = read_tree_block(found_root, extent_key->objectid,
2766 extent_key->offset, 0); 2773 extent_key->offset, 0);
@@ -2782,26 +2789,40 @@ static int noinline relocate_one_reference(struct btrfs_root *extent_root,
2782 if (ret) 2789 if (ret)
2783 goto out; 2790 goto out;
2784 2791
2792 /*
2793 * right here almost anything could happen to our key,
2794 * but that's ok. The cow below will either relocate it
2795 * or someone else will have relocated it. Either way,
2796 * it is in a different spot than it was before and
2797 * we're happy.
2798 */
2799
2785 trans = btrfs_start_transaction(found_root, 1); 2800 trans = btrfs_start_transaction(found_root, 1);
2786 2801
2802 if (found_root == extent_root->fs_info->extent_root ||
2803 found_root == extent_root->fs_info->chunk_root ||
2804 found_root == extent_root->fs_info->dev_root) {
2805 needs_lock = 1;
2806 mutex_lock(&extent_root->fs_info->alloc_mutex);
2807 }
2808
2787 path->lowest_level = level; 2809 path->lowest_level = level;
2788 path->reada = 2; 2810 path->reada = 2;
2789 ret = btrfs_search_slot(trans, found_root, &found_key, path, 2811 ret = btrfs_search_slot(trans, found_root, &found_key, path,
2790 0, 1); 2812 0, 1);
2791 path->lowest_level = 0; 2813 path->lowest_level = 0;
2792 for (i = level; i < BTRFS_MAX_LEVEL; i++) {
2793 if (!path->nodes[i])
2794 break;
2795 free_extent_buffer(path->nodes[i]);
2796 path->nodes[i] = NULL;
2797 }
2798 btrfs_release_path(found_root, path); 2814 btrfs_release_path(found_root, path);
2815
2799 if (found_root == found_root->fs_info->extent_root) 2816 if (found_root == found_root->fs_info->extent_root)
2800 btrfs_extent_post_op(trans, found_root); 2817 btrfs_extent_post_op(trans, found_root);
2818 if (needs_lock)
2819 mutex_unlock(&extent_root->fs_info->alloc_mutex);
2820
2801 btrfs_end_transaction(trans, found_root); 2821 btrfs_end_transaction(trans, found_root);
2802 }
2803 2822
2823 }
2804out: 2824out:
2825 mutex_lock(&extent_root->fs_info->alloc_mutex);
2805 return 0; 2826 return 0;
2806} 2827}
2807 2828
@@ -2943,7 +2964,10 @@ int __alloc_chunk_for_shrink(struct btrfs_root *root,
2943 2964
2944 if (btrfs_block_group_used(&shrink_block_group->item) > 0) { 2965 if (btrfs_block_group_used(&shrink_block_group->item) > 0) {
2945 2966
2967 mutex_unlock(&root->fs_info->alloc_mutex);
2946 trans = btrfs_start_transaction(root, 1); 2968 trans = btrfs_start_transaction(root, 1);
2969 mutex_lock(&root->fs_info->alloc_mutex);
2970
2947 new_alloc_flags = update_block_group_flags(root, 2971 new_alloc_flags = update_block_group_flags(root,
2948 shrink_block_group->flags); 2972 shrink_block_group->flags);
2949 if (new_alloc_flags != shrink_block_group->flags) { 2973 if (new_alloc_flags != shrink_block_group->flags) {
@@ -2954,7 +2978,10 @@ int __alloc_chunk_for_shrink(struct btrfs_root *root,
2954 } 2978 }
2955 do_chunk_alloc(trans, root->fs_info->extent_root, 2979 do_chunk_alloc(trans, root->fs_info->extent_root,
2956 calc + 2 * 1024 * 1024, new_alloc_flags, force); 2980 calc + 2 * 1024 * 1024, new_alloc_flags, force);
2981
2982 mutex_unlock(&root->fs_info->alloc_mutex);
2957 btrfs_end_transaction(trans, root); 2983 btrfs_end_transaction(trans, root);
2984 mutex_lock(&root->fs_info->alloc_mutex);
2958 } 2985 }
2959 return 0; 2986 return 0;
2960} 2987}
@@ -3031,9 +3058,9 @@ again:
3031 if (ret < 0) 3058 if (ret < 0)
3032 goto out; 3059 goto out;
3033 3060
3061next:
3034 leaf = path->nodes[0]; 3062 leaf = path->nodes[0];
3035 nritems = btrfs_header_nritems(leaf); 3063 nritems = btrfs_header_nritems(leaf);
3036next:
3037 if (path->slots[0] >= nritems) { 3064 if (path->slots[0] >= nritems) {
3038 ret = btrfs_next_leaf(root, path); 3065 ret = btrfs_next_leaf(root, path);
3039 if (ret < 0) 3066 if (ret < 0)
@@ -3083,6 +3110,7 @@ next:
3083 printk("btrfs relocate found %llu last extent was %llu\n", 3110 printk("btrfs relocate found %llu last extent was %llu\n",
3084 (unsigned long long)total_found, 3111 (unsigned long long)total_found,
3085 (unsigned long long)found_key.objectid); 3112 (unsigned long long)found_key.objectid);
3113 mutex_unlock(&root->fs_info->alloc_mutex);
3086 trans = btrfs_start_transaction(tree_root, 1); 3114 trans = btrfs_start_transaction(tree_root, 1);
3087 btrfs_commit_transaction(trans, tree_root); 3115 btrfs_commit_transaction(trans, tree_root);
3088 3116
@@ -3090,6 +3118,7 @@ next:
3090 3118
3091 trans = btrfs_start_transaction(tree_root, 1); 3119 trans = btrfs_start_transaction(tree_root, 1);
3092 btrfs_commit_transaction(trans, tree_root); 3120 btrfs_commit_transaction(trans, tree_root);
3121 mutex_lock(&root->fs_info->alloc_mutex);
3093 goto again; 3122 goto again;
3094 } 3123 }
3095 3124
@@ -3097,7 +3126,10 @@ next:
3097 * we've freed all the extents, now remove the block 3126 * we've freed all the extents, now remove the block
3098 * group item from the tree 3127 * group item from the tree
3099 */ 3128 */
3129 mutex_unlock(&root->fs_info->alloc_mutex);
3130
3100 trans = btrfs_start_transaction(root, 1); 3131 trans = btrfs_start_transaction(root, 1);
3132 mutex_lock(&root->fs_info->alloc_mutex);
3101 memcpy(&key, &shrink_block_group->key, sizeof(key)); 3133 memcpy(&key, &shrink_block_group->key, sizeof(key));
3102 3134
3103 ret = btrfs_search_slot(trans, root, &key, path, -1, 1); 3135 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
@@ -3119,8 +3151,12 @@ next:
3119 kfree(shrink_block_group); 3151 kfree(shrink_block_group);
3120 3152
3121 btrfs_del_item(trans, root, path); 3153 btrfs_del_item(trans, root, path);
3154 btrfs_release_path(root, path);
3155 mutex_unlock(&root->fs_info->alloc_mutex);
3122 btrfs_commit_transaction(trans, root); 3156 btrfs_commit_transaction(trans, root);
3123 3157
3158 mutex_lock(&root->fs_info->alloc_mutex);
3159
3124 /* the code to unpin extents might set a few bits in the free 3160 /* the code to unpin extents might set a few bits in the free
3125 * space cache for this range again 3161 * space cache for this range again
3126 */ 3162 */
@@ -3263,6 +3299,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
3263 struct btrfs_block_group_cache *cache; 3299 struct btrfs_block_group_cache *cache;
3264 struct extent_io_tree *block_group_cache; 3300 struct extent_io_tree *block_group_cache;
3265 3301
3302 WARN_ON(!mutex_is_locked(&root->fs_info->alloc_mutex));
3266 extent_root = root->fs_info->extent_root; 3303 extent_root = root->fs_info->extent_root;
3267 block_group_cache = &root->fs_info->block_group_cache; 3304 block_group_cache = &root->fs_info->block_group_cache;
3268 3305