aboutsummaryrefslogtreecommitdiffstats
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
parenta7a16fd772620605c76e8ac8bdbc8ccc9e3df1a0 (diff)
Btrfs: Add locking around volume management (device add/remove/balance)
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/ctree.c4
-rw-r--r--fs/btrfs/ctree.h1
-rw-r--r--fs/btrfs/disk-io.c1
-rw-r--r--fs/btrfs/extent-tree.c73
-rw-r--r--fs/btrfs/ioctl.c6
-rw-r--r--fs/btrfs/volumes.c58
6 files changed, 103 insertions, 40 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index c6759fc1004a..bbf9bf374066 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1251,10 +1251,6 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
1251 WARN_ON(p->nodes[0] != NULL); 1251 WARN_ON(p->nodes[0] != NULL);
1252 WARN_ON(cow && root == root->fs_info->extent_root && 1252 WARN_ON(cow && root == root->fs_info->extent_root &&
1253 !mutex_is_locked(&root->fs_info->alloc_mutex)); 1253 !mutex_is_locked(&root->fs_info->alloc_mutex));
1254 WARN_ON(root == root->fs_info->chunk_root &&
1255 !mutex_is_locked(&root->fs_info->chunk_mutex));
1256 WARN_ON(root == root->fs_info->dev_root &&
1257 !mutex_is_locked(&root->fs_info->chunk_mutex));
1258 if (ins_len < 0) 1254 if (ins_len < 0)
1259 lowest_unlock = 2; 1255 lowest_unlock = 2;
1260again: 1256again:
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index a28796482b4a..f3783dbd9b60 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -523,6 +523,7 @@ struct btrfs_fs_info {
523 struct mutex alloc_mutex; 523 struct mutex alloc_mutex;
524 struct mutex chunk_mutex; 524 struct mutex chunk_mutex;
525 struct mutex drop_mutex; 525 struct mutex drop_mutex;
526 struct mutex volume_mutex;
526 struct list_head trans_list; 527 struct list_head trans_list;
527 struct list_head hashers; 528 struct list_head hashers;
528 struct list_head dead_roots; 529 struct list_head dead_roots;
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 4cdc0b6a2672..8f4c40033e92 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1287,6 +1287,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1287 mutex_init(&fs_info->chunk_mutex); 1287 mutex_init(&fs_info->chunk_mutex);
1288 mutex_init(&fs_info->transaction_kthread_mutex); 1288 mutex_init(&fs_info->transaction_kthread_mutex);
1289 mutex_init(&fs_info->cleaner_mutex); 1289 mutex_init(&fs_info->cleaner_mutex);
1290 mutex_init(&fs_info->volume_mutex);
1290 1291
1291#if 0 1292#if 0
1292 ret = add_hasher(fs_info, "crc32c"); 1293 ret = add_hasher(fs_info, "crc32c");
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
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 026039a2ac58..83f17a5cbd6a 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -307,8 +307,7 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
307 goto out; 307 goto out;
308 } 308 }
309 309
310 mutex_lock(&root->fs_info->alloc_mutex); 310 mutex_lock(&root->fs_info->volume_mutex);
311 mutex_lock(&root->fs_info->chunk_mutex);
312 sizestr = vol_args->name; 311 sizestr = vol_args->name;
313 devstr = strchr(sizestr, ':'); 312 devstr = strchr(sizestr, ':');
314 if (devstr) { 313 if (devstr) {
@@ -378,8 +377,7 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
378 } 377 }
379 378
380out_unlock: 379out_unlock:
381 mutex_lock(&root->fs_info->alloc_mutex); 380 mutex_unlock(&root->fs_info->volume_mutex);
382 mutex_lock(&root->fs_info->chunk_mutex);
383out: 381out:
384 kfree(vol_args); 382 kfree(vol_args);
385 return ret; 383 return ret;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 4e7cee27aab5..5e6ee7a6f738 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -56,6 +56,18 @@ void btrfs_unlock_volumes(void)
56 mutex_unlock(&uuid_mutex); 56 mutex_unlock(&uuid_mutex);
57} 57}
58 58
59static void lock_chunks(struct btrfs_root *root)
60{
61 mutex_lock(&root->fs_info->alloc_mutex);
62 mutex_lock(&root->fs_info->chunk_mutex);
63}
64
65static void unlock_chunks(struct btrfs_root *root)
66{
67 mutex_unlock(&root->fs_info->alloc_mutex);
68 mutex_unlock(&root->fs_info->chunk_mutex);
69}
70
59int btrfs_cleanup_fs_uuids(void) 71int btrfs_cleanup_fs_uuids(void)
60{ 72{
61 struct btrfs_fs_devices *fs_devices; 73 struct btrfs_fs_devices *fs_devices;
@@ -822,6 +834,7 @@ static int btrfs_rm_dev_item(struct btrfs_root *root,
822 key.objectid = BTRFS_DEV_ITEMS_OBJECTID; 834 key.objectid = BTRFS_DEV_ITEMS_OBJECTID;
823 key.type = BTRFS_DEV_ITEM_KEY; 835 key.type = BTRFS_DEV_ITEM_KEY;
824 key.offset = device->devid; 836 key.offset = device->devid;
837 lock_chunks(root);
825 838
826 ret = btrfs_search_slot(trans, root, &key, path, -1, 1); 839 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
827 if (ret < 0) 840 if (ret < 0)
@@ -856,6 +869,7 @@ static int btrfs_rm_dev_item(struct btrfs_root *root,
856 total_bytes - 1); 869 total_bytes - 1);
857out: 870out:
858 btrfs_free_path(path); 871 btrfs_free_path(path);
872 unlock_chunks(root);
859 btrfs_commit_transaction(trans, root); 873 btrfs_commit_transaction(trans, root);
860 return ret; 874 return ret;
861} 875}
@@ -870,9 +884,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
870 u64 devid; 884 u64 devid;
871 int ret = 0; 885 int ret = 0;
872 886
873 mutex_lock(&root->fs_info->alloc_mutex);
874 mutex_lock(&root->fs_info->chunk_mutex);
875 mutex_lock(&uuid_mutex); 887 mutex_lock(&uuid_mutex);
888 mutex_lock(&root->fs_info->volume_mutex);
876 889
877 all_avail = root->fs_info->avail_data_alloc_bits | 890 all_avail = root->fs_info->avail_data_alloc_bits |
878 root->fs_info->avail_system_alloc_bits | 891 root->fs_info->avail_system_alloc_bits |
@@ -988,9 +1001,8 @@ error_close:
988 if (bdev) 1001 if (bdev)
989 close_bdev_excl(bdev); 1002 close_bdev_excl(bdev);
990out: 1003out:
1004 mutex_unlock(&root->fs_info->volume_mutex);
991 mutex_unlock(&uuid_mutex); 1005 mutex_unlock(&uuid_mutex);
992 mutex_unlock(&root->fs_info->chunk_mutex);
993 mutex_unlock(&root->fs_info->alloc_mutex);
994 return ret; 1006 return ret;
995} 1007}
996 1008
@@ -1010,10 +1022,10 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
1010 return -EIO; 1022 return -EIO;
1011 } 1023 }
1012 1024
1013 mutex_lock(&root->fs_info->alloc_mutex); 1025 mutex_lock(&root->fs_info->volume_mutex);
1014 mutex_lock(&root->fs_info->chunk_mutex);
1015 1026
1016 trans = btrfs_start_transaction(root, 1); 1027 trans = btrfs_start_transaction(root, 1);
1028 lock_chunks(root);
1017 devices = &root->fs_info->fs_devices->devices; 1029 devices = &root->fs_info->fs_devices->devices;
1018 list_for_each(cur, devices) { 1030 list_for_each(cur, devices) {
1019 device = list_entry(cur, struct btrfs_device, dev_list); 1031 device = list_entry(cur, struct btrfs_device, dev_list);
@@ -1065,9 +1077,9 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path)
1065 root->fs_info->fs_devices->num_devices++; 1077 root->fs_info->fs_devices->num_devices++;
1066 root->fs_info->fs_devices->open_devices++; 1078 root->fs_info->fs_devices->open_devices++;
1067out: 1079out:
1080 unlock_chunks(root);
1068 btrfs_end_transaction(trans, root); 1081 btrfs_end_transaction(trans, root);
1069 mutex_unlock(&root->fs_info->chunk_mutex); 1082 mutex_unlock(&root->fs_info->volume_mutex);
1070 mutex_unlock(&root->fs_info->alloc_mutex);
1071 1083
1072 return ret; 1084 return ret;
1073 1085
@@ -1122,7 +1134,7 @@ out:
1122 return ret; 1134 return ret;
1123} 1135}
1124 1136
1125int btrfs_grow_device(struct btrfs_trans_handle *trans, 1137static int __btrfs_grow_device(struct btrfs_trans_handle *trans,
1126 struct btrfs_device *device, u64 new_size) 1138 struct btrfs_device *device, u64 new_size)
1127{ 1139{
1128 struct btrfs_super_block *super_copy = 1140 struct btrfs_super_block *super_copy =
@@ -1134,6 +1146,16 @@ int btrfs_grow_device(struct btrfs_trans_handle *trans,
1134 return btrfs_update_device(trans, device); 1146 return btrfs_update_device(trans, device);
1135} 1147}
1136 1148
1149int btrfs_grow_device(struct btrfs_trans_handle *trans,
1150 struct btrfs_device *device, u64 new_size)
1151{
1152 int ret;
1153 lock_chunks(device->dev_root);
1154 ret = __btrfs_grow_device(trans, device, new_size);
1155 unlock_chunks(device->dev_root);
1156 return ret;
1157}
1158
1137static int btrfs_free_chunk(struct btrfs_trans_handle *trans, 1159static int btrfs_free_chunk(struct btrfs_trans_handle *trans,
1138 struct btrfs_root *root, 1160 struct btrfs_root *root,
1139 u64 chunk_tree, u64 chunk_objectid, 1161 u64 chunk_tree, u64 chunk_objectid,
@@ -1234,6 +1256,8 @@ int btrfs_relocate_chunk(struct btrfs_root *root,
1234 trans = btrfs_start_transaction(root, 1); 1256 trans = btrfs_start_transaction(root, 1);
1235 BUG_ON(!trans); 1257 BUG_ON(!trans);
1236 1258
1259 lock_chunks(root);
1260
1237 /* 1261 /*
1238 * step two, delete the device extents and the 1262 * step two, delete the device extents and the
1239 * chunk tree entries 1263 * chunk tree entries
@@ -1278,6 +1302,7 @@ int btrfs_relocate_chunk(struct btrfs_root *root,
1278 /* once for us */ 1302 /* once for us */
1279 free_extent_map(em); 1303 free_extent_map(em);
1280 1304
1305 unlock_chunks(root);
1281 btrfs_end_transaction(trans, root); 1306 btrfs_end_transaction(trans, root);
1282 return 0; 1307 return 0;
1283} 1308}
@@ -1308,8 +1333,7 @@ int btrfs_balance(struct btrfs_root *dev_root)
1308 struct btrfs_key found_key; 1333 struct btrfs_key found_key;
1309 1334
1310 1335
1311 BUG(); /* FIXME, needs locking */ 1336 mutex_lock(&dev_root->fs_info->volume_mutex);
1312
1313 dev_root = dev_root->fs_info->dev_root; 1337 dev_root = dev_root->fs_info->dev_root;
1314 1338
1315 /* step one make some room on all the devices */ 1339 /* step one make some room on all the devices */
@@ -1355,13 +1379,14 @@ int btrfs_balance(struct btrfs_root *dev_root)
1355 1379
1356 ret = btrfs_previous_item(chunk_root, path, 0, 1380 ret = btrfs_previous_item(chunk_root, path, 0,
1357 BTRFS_CHUNK_ITEM_KEY); 1381 BTRFS_CHUNK_ITEM_KEY);
1358 if (ret) { 1382 if (ret)
1359 break; 1383 break;
1360 } 1384
1361 btrfs_item_key_to_cpu(path->nodes[0], &found_key, 1385 btrfs_item_key_to_cpu(path->nodes[0], &found_key,
1362 path->slots[0]); 1386 path->slots[0]);
1363 if (found_key.objectid != key.objectid) 1387 if (found_key.objectid != key.objectid)
1364 break; 1388 break;
1389
1365 chunk = btrfs_item_ptr(path->nodes[0], 1390 chunk = btrfs_item_ptr(path->nodes[0],
1366 path->slots[0], 1391 path->slots[0],
1367 struct btrfs_chunk); 1392 struct btrfs_chunk);
@@ -1370,16 +1395,17 @@ int btrfs_balance(struct btrfs_root *dev_root)
1370 if (key.offset == 0) 1395 if (key.offset == 0)
1371 break; 1396 break;
1372 1397
1398 btrfs_release_path(chunk_root, path);
1373 ret = btrfs_relocate_chunk(chunk_root, 1399 ret = btrfs_relocate_chunk(chunk_root,
1374 chunk_root->root_key.objectid, 1400 chunk_root->root_key.objectid,
1375 found_key.objectid, 1401 found_key.objectid,
1376 found_key.offset); 1402 found_key.offset);
1377 BUG_ON(ret); 1403 BUG_ON(ret);
1378 btrfs_release_path(chunk_root, path);
1379 } 1404 }
1380 ret = 0; 1405 ret = 0;
1381error: 1406error:
1382 btrfs_free_path(path); 1407 btrfs_free_path(path);
1408 mutex_unlock(&dev_root->fs_info->volume_mutex);
1383 return ret; 1409 return ret;
1384} 1410}
1385 1411
@@ -1419,14 +1445,18 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
1419 1445
1420 path->reada = 2; 1446 path->reada = 2;
1421 1447
1448 lock_chunks(root);
1449
1422 device->total_bytes = new_size; 1450 device->total_bytes = new_size;
1423 ret = btrfs_update_device(trans, device); 1451 ret = btrfs_update_device(trans, device);
1424 if (ret) { 1452 if (ret) {
1453 unlock_chunks(root);
1425 btrfs_end_transaction(trans, root); 1454 btrfs_end_transaction(trans, root);
1426 goto done; 1455 goto done;
1427 } 1456 }
1428 WARN_ON(diff > old_total); 1457 WARN_ON(diff > old_total);
1429 btrfs_set_super_total_bytes(super_copy, old_total - diff); 1458 btrfs_set_super_total_bytes(super_copy, old_total - diff);
1459 unlock_chunks(root);
1430 btrfs_end_transaction(trans, root); 1460 btrfs_end_transaction(trans, root);
1431 1461
1432 key.objectid = device->devid; 1462 key.objectid = device->devid;