aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c69
1 files changed, 50 insertions, 19 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index a421c32c6cfe..8933d15a240f 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -56,9 +56,6 @@ static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans,
56 int ref_mod); 56 int ref_mod);
57static int update_reserved_extents(struct btrfs_root *root, 57static int update_reserved_extents(struct btrfs_root *root,
58 u64 bytenr, u64 num, int reserve); 58 u64 bytenr, u64 num, int reserve);
59static int pin_down_bytes(struct btrfs_trans_handle *trans,
60 struct btrfs_root *root,
61 u64 bytenr, u64 num_bytes, int is_data);
62static int update_block_group(struct btrfs_trans_handle *trans, 59static int update_block_group(struct btrfs_trans_handle *trans,
63 struct btrfs_root *root, 60 struct btrfs_root *root,
64 u64 bytenr, u64 num_bytes, int alloc, 61 u64 bytenr, u64 num_bytes, int alloc,
@@ -618,6 +615,7 @@ static noinline int insert_extent_backref(struct btrfs_trans_handle *trans,
618 } else { 615 } else {
619 goto out; 616 goto out;
620 } 617 }
618 btrfs_unlock_up_safe(path, 1);
621 btrfs_mark_buffer_dirty(path->nodes[0]); 619 btrfs_mark_buffer_dirty(path->nodes[0]);
622out: 620out:
623 btrfs_release_path(root, path); 621 btrfs_release_path(root, path);
@@ -760,6 +758,7 @@ static noinline_for_stack int add_extent_ref(struct btrfs_trans_handle *trans,
760 return -ENOMEM; 758 return -ENOMEM;
761 759
762 path->reada = 1; 760 path->reada = 1;
761 path->leave_spinning = 1;
763 key.objectid = bytenr; 762 key.objectid = bytenr;
764 key.type = BTRFS_EXTENT_ITEM_KEY; 763 key.type = BTRFS_EXTENT_ITEM_KEY;
765 key.offset = num_bytes; 764 key.offset = num_bytes;
@@ -767,8 +766,10 @@ static noinline_for_stack int add_extent_ref(struct btrfs_trans_handle *trans,
767 /* first find the extent item and update its reference count */ 766 /* first find the extent item and update its reference count */
768 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key, 767 ret = btrfs_search_slot(trans, root->fs_info->extent_root, &key,
769 path, 0, 1); 768 path, 0, 1);
770 if (ret < 0) 769 if (ret < 0) {
770 btrfs_set_path_blocking(path);
771 return ret; 771 return ret;
772 }
772 773
773 if (ret > 0) { 774 if (ret > 0) {
774 WARN_ON(1); 775 WARN_ON(1);
@@ -791,11 +792,15 @@ static noinline_for_stack int add_extent_ref(struct btrfs_trans_handle *trans,
791 792
792 refs = btrfs_extent_refs(l, item); 793 refs = btrfs_extent_refs(l, item);
793 btrfs_set_extent_refs(l, item, refs + refs_to_add); 794 btrfs_set_extent_refs(l, item, refs + refs_to_add);
795 btrfs_unlock_up_safe(path, 1);
796
794 btrfs_mark_buffer_dirty(path->nodes[0]); 797 btrfs_mark_buffer_dirty(path->nodes[0]);
795 798
796 btrfs_release_path(root->fs_info->extent_root, path); 799 btrfs_release_path(root->fs_info->extent_root, path);
797 800
798 path->reada = 1; 801 path->reada = 1;
802 path->leave_spinning = 1;
803
799 /* now insert the actual backref */ 804 /* now insert the actual backref */
800 ret = insert_extent_backref(trans, root->fs_info->extent_root, 805 ret = insert_extent_backref(trans, root->fs_info->extent_root,
801 path, bytenr, parent, 806 path, bytenr, parent,
@@ -2050,6 +2055,8 @@ int btrfs_update_pinned_extents(struct btrfs_root *root,
2050 clear_extent_dirty(&fs_info->pinned_extents, 2055 clear_extent_dirty(&fs_info->pinned_extents,
2051 bytenr, bytenr + num - 1, GFP_NOFS); 2056 bytenr, bytenr + num - 1, GFP_NOFS);
2052 } 2057 }
2058 mutex_unlock(&root->fs_info->pinned_mutex);
2059
2053 while (num > 0) { 2060 while (num > 0) {
2054 cache = btrfs_lookup_block_group(fs_info, bytenr); 2061 cache = btrfs_lookup_block_group(fs_info, bytenr);
2055 BUG_ON(!cache); 2062 BUG_ON(!cache);
@@ -2141,8 +2148,8 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
2141 u64 end; 2148 u64 end;
2142 int ret; 2149 int ret;
2143 2150
2144 mutex_lock(&root->fs_info->pinned_mutex);
2145 while (1) { 2151 while (1) {
2152 mutex_lock(&root->fs_info->pinned_mutex);
2146 ret = find_first_extent_bit(unpin, 0, &start, &end, 2153 ret = find_first_extent_bit(unpin, 0, &start, &end,
2147 EXTENT_DIRTY); 2154 EXTENT_DIRTY);
2148 if (ret) 2155 if (ret)
@@ -2150,14 +2157,11 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
2150 2157
2151 ret = btrfs_discard_extent(root, start, end + 1 - start); 2158 ret = btrfs_discard_extent(root, start, end + 1 - start);
2152 2159
2160 /* unlocks the pinned mutex */
2153 btrfs_update_pinned_extents(root, start, end + 1 - start, 0); 2161 btrfs_update_pinned_extents(root, start, end + 1 - start, 0);
2154 clear_extent_dirty(unpin, start, end, GFP_NOFS); 2162 clear_extent_dirty(unpin, start, end, GFP_NOFS);
2155 2163
2156 if (need_resched()) { 2164 cond_resched();
2157 mutex_unlock(&root->fs_info->pinned_mutex);
2158 cond_resched();
2159 mutex_lock(&root->fs_info->pinned_mutex);
2160 }
2161 } 2165 }
2162 mutex_unlock(&root->fs_info->pinned_mutex); 2166 mutex_unlock(&root->fs_info->pinned_mutex);
2163 return ret; 2167 return ret;
@@ -2165,7 +2169,9 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
2165 2169
2166static int pin_down_bytes(struct btrfs_trans_handle *trans, 2170static int pin_down_bytes(struct btrfs_trans_handle *trans,
2167 struct btrfs_root *root, 2171 struct btrfs_root *root,
2168 u64 bytenr, u64 num_bytes, int is_data) 2172 struct btrfs_path *path,
2173 u64 bytenr, u64 num_bytes, int is_data,
2174 struct extent_buffer **must_clean)
2169{ 2175{
2170 int err = 0; 2176 int err = 0;
2171 struct extent_buffer *buf; 2177 struct extent_buffer *buf;
@@ -2191,15 +2197,16 @@ static int pin_down_bytes(struct btrfs_trans_handle *trans,
2191 header_owner != BTRFS_DATA_RELOC_TREE_OBJECTID && 2197 header_owner != BTRFS_DATA_RELOC_TREE_OBJECTID &&
2192 header_transid == trans->transid && 2198 header_transid == trans->transid &&
2193 !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) { 2199 !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) {
2194 clean_tree_block(NULL, root, buf); 2200 *must_clean = buf;
2195 btrfs_tree_unlock(buf);
2196 free_extent_buffer(buf);
2197 return 1; 2201 return 1;
2198 } 2202 }
2199 btrfs_tree_unlock(buf); 2203 btrfs_tree_unlock(buf);
2200 } 2204 }
2201 free_extent_buffer(buf); 2205 free_extent_buffer(buf);
2202pinit: 2206pinit:
2207 btrfs_set_path_blocking(path);
2208 mutex_lock(&root->fs_info->pinned_mutex);
2209 /* unlocks the pinned mutex */
2203 btrfs_update_pinned_extents(root, bytenr, num_bytes, 1); 2210 btrfs_update_pinned_extents(root, bytenr, num_bytes, 1);
2204 2211
2205 BUG_ON(err < 0); 2212 BUG_ON(err < 0);
@@ -2236,6 +2243,7 @@ static int __free_extent(struct btrfs_trans_handle *trans,
2236 return -ENOMEM; 2243 return -ENOMEM;
2237 2244
2238 path->reada = 1; 2245 path->reada = 1;
2246 path->leave_spinning = 1;
2239 ret = lookup_extent_backref(trans, extent_root, path, 2247 ret = lookup_extent_backref(trans, extent_root, path,
2240 bytenr, parent, root_objectid, 2248 bytenr, parent, root_objectid,
2241 ref_generation, owner_objectid, 1); 2249 ref_generation, owner_objectid, 1);
@@ -2261,6 +2269,7 @@ static int __free_extent(struct btrfs_trans_handle *trans,
2261 refs_to_drop); 2269 refs_to_drop);
2262 BUG_ON(ret); 2270 BUG_ON(ret);
2263 btrfs_release_path(extent_root, path); 2271 btrfs_release_path(extent_root, path);
2272 path->leave_spinning = 1;
2264 ret = btrfs_search_slot(trans, extent_root, 2273 ret = btrfs_search_slot(trans, extent_root,
2265 &key, path, -1, 1); 2274 &key, path, -1, 1);
2266 if (ret) { 2275 if (ret) {
@@ -2318,6 +2327,7 @@ static int __free_extent(struct btrfs_trans_handle *trans,
2318 /* if refs are 0, we need to setup the path for deletion */ 2327 /* if refs are 0, we need to setup the path for deletion */
2319 if (refs == 0) { 2328 if (refs == 0) {
2320 btrfs_release_path(extent_root, path); 2329 btrfs_release_path(extent_root, path);
2330 path->leave_spinning = 1;
2321 ret = btrfs_search_slot(trans, extent_root, &key, path, 2331 ret = btrfs_search_slot(trans, extent_root, &key, path,
2322 -1, 1); 2332 -1, 1);
2323 BUG_ON(ret); 2333 BUG_ON(ret);
@@ -2327,16 +2337,18 @@ static int __free_extent(struct btrfs_trans_handle *trans,
2327 if (refs == 0) { 2337 if (refs == 0) {
2328 u64 super_used; 2338 u64 super_used;
2329 u64 root_used; 2339 u64 root_used;
2340 struct extent_buffer *must_clean = NULL;
2330 2341
2331 if (pin) { 2342 if (pin) {
2332 mutex_lock(&root->fs_info->pinned_mutex); 2343 ret = pin_down_bytes(trans, root, path,
2333 ret = pin_down_bytes(trans, root, bytenr, num_bytes, 2344 bytenr, num_bytes,
2334 owner_objectid >= BTRFS_FIRST_FREE_OBJECTID); 2345 owner_objectid >= BTRFS_FIRST_FREE_OBJECTID,
2335 mutex_unlock(&root->fs_info->pinned_mutex); 2346 &must_clean);
2336 if (ret > 0) 2347 if (ret > 0)
2337 mark_free = 1; 2348 mark_free = 1;
2338 BUG_ON(ret < 0); 2349 BUG_ON(ret < 0);
2339 } 2350 }
2351
2340 /* block accounting for super block */ 2352 /* block accounting for super block */
2341 spin_lock(&info->delalloc_lock); 2353 spin_lock(&info->delalloc_lock);
2342 super_used = btrfs_super_bytes_used(&info->super_copy); 2354 super_used = btrfs_super_bytes_used(&info->super_copy);
@@ -2348,11 +2360,27 @@ static int __free_extent(struct btrfs_trans_handle *trans,
2348 btrfs_set_root_used(&root->root_item, 2360 btrfs_set_root_used(&root->root_item,
2349 root_used - num_bytes); 2361 root_used - num_bytes);
2350 spin_unlock(&info->delalloc_lock); 2362 spin_unlock(&info->delalloc_lock);
2363
2364 /*
2365 * it is going to be very rare for someone to be waiting
2366 * on the block we're freeing. del_items might need to
2367 * schedule, so rather than get fancy, just force it
2368 * to blocking here
2369 */
2370 if (must_clean)
2371 btrfs_set_lock_blocking(must_clean);
2372
2351 ret = btrfs_del_items(trans, extent_root, path, path->slots[0], 2373 ret = btrfs_del_items(trans, extent_root, path, path->slots[0],
2352 num_to_del); 2374 num_to_del);
2353 BUG_ON(ret); 2375 BUG_ON(ret);
2354 btrfs_release_path(extent_root, path); 2376 btrfs_release_path(extent_root, path);
2355 2377
2378 if (must_clean) {
2379 clean_tree_block(NULL, root, must_clean);
2380 btrfs_tree_unlock(must_clean);
2381 free_extent_buffer(must_clean);
2382 }
2383
2356 if (owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) { 2384 if (owner_objectid >= BTRFS_FIRST_FREE_OBJECTID) {
2357 ret = btrfs_del_csums(trans, root, bytenr, num_bytes); 2385 ret = btrfs_del_csums(trans, root, bytenr, num_bytes);
2358 BUG_ON(ret); 2386 BUG_ON(ret);
@@ -2480,8 +2508,9 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans,
2480 if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID && 2508 if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID &&
2481 owner_objectid < BTRFS_FIRST_FREE_OBJECTID) { 2509 owner_objectid < BTRFS_FIRST_FREE_OBJECTID) {
2482 mutex_lock(&root->fs_info->pinned_mutex); 2510 mutex_lock(&root->fs_info->pinned_mutex);
2511
2512 /* unlocks the pinned mutex */
2483 btrfs_update_pinned_extents(root, bytenr, num_bytes, 1); 2513 btrfs_update_pinned_extents(root, bytenr, num_bytes, 1);
2484 mutex_unlock(&root->fs_info->pinned_mutex);
2485 update_reserved_extents(root, bytenr, num_bytes, 0); 2514 update_reserved_extents(root, bytenr, num_bytes, 0);
2486 ret = 0; 2515 ret = 0;
2487 } else { 2516 } else {
@@ -2931,6 +2960,7 @@ static int __btrfs_alloc_reserved_extent(struct btrfs_trans_handle *trans,
2931 path = btrfs_alloc_path(); 2960 path = btrfs_alloc_path();
2932 BUG_ON(!path); 2961 BUG_ON(!path);
2933 2962
2963 path->leave_spinning = 1;
2934 ret = btrfs_insert_empty_items(trans, extent_root, path, keys, 2964 ret = btrfs_insert_empty_items(trans, extent_root, path, keys,
2935 sizes, 2); 2965 sizes, 2);
2936 BUG_ON(ret); 2966 BUG_ON(ret);
@@ -5435,6 +5465,7 @@ static int __insert_orphan_inode(struct btrfs_trans_handle *trans,
5435 if (!path) 5465 if (!path)
5436 return -ENOMEM; 5466 return -ENOMEM;
5437 5467
5468 path->leave_spinning = 1;
5438 ret = btrfs_insert_empty_inode(trans, root, path, objectid); 5469 ret = btrfs_insert_empty_inode(trans, root, path, objectid);
5439 if (ret) 5470 if (ret)
5440 goto out; 5471 goto out;