diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 73 |
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 | } | ||
2804 | out: | 2824 | out: |
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 | ||
3061 | next: | ||
3034 | leaf = path->nodes[0]; | 3062 | leaf = path->nodes[0]; |
3035 | nritems = btrfs_header_nritems(leaf); | 3063 | nritems = btrfs_header_nritems(leaf); |
3036 | next: | ||
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 | ||