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.c90
1 files changed, 57 insertions, 33 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 1eef4ee01d1a..0ec8e228b89f 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3178,8 +3178,8 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans,
3178 bi = btrfs_item_ptr_offset(leaf, path->slots[0]); 3178 bi = btrfs_item_ptr_offset(leaf, path->slots[0]);
3179 write_extent_buffer(leaf, &cache->item, bi, sizeof(cache->item)); 3179 write_extent_buffer(leaf, &cache->item, bi, sizeof(cache->item));
3180 btrfs_mark_buffer_dirty(leaf); 3180 btrfs_mark_buffer_dirty(leaf);
3181 btrfs_release_path(path);
3182fail: 3181fail:
3182 btrfs_release_path(path);
3183 if (ret) 3183 if (ret)
3184 btrfs_abort_transaction(trans, root, ret); 3184 btrfs_abort_transaction(trans, root, ret);
3185 return ret; 3185 return ret;
@@ -3305,8 +3305,7 @@ again:
3305 3305
3306 spin_lock(&block_group->lock); 3306 spin_lock(&block_group->lock);
3307 if (block_group->cached != BTRFS_CACHE_FINISHED || 3307 if (block_group->cached != BTRFS_CACHE_FINISHED ||
3308 !btrfs_test_opt(root, SPACE_CACHE) || 3308 !btrfs_test_opt(root, SPACE_CACHE)) {
3309 block_group->delalloc_bytes) {
3310 /* 3309 /*
3311 * don't bother trying to write stuff out _if_ 3310 * don't bother trying to write stuff out _if_
3312 * a) we're not cached, 3311 * a) we're not cached,
@@ -3408,17 +3407,14 @@ int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans,
3408 int loops = 0; 3407 int loops = 0;
3409 3408
3410 spin_lock(&cur_trans->dirty_bgs_lock); 3409 spin_lock(&cur_trans->dirty_bgs_lock);
3411 if (!list_empty(&cur_trans->dirty_bgs)) { 3410 if (list_empty(&cur_trans->dirty_bgs)) {
3412 list_splice_init(&cur_trans->dirty_bgs, &dirty); 3411 spin_unlock(&cur_trans->dirty_bgs_lock);
3412 return 0;
3413 } 3413 }
3414 list_splice_init(&cur_trans->dirty_bgs, &dirty);
3414 spin_unlock(&cur_trans->dirty_bgs_lock); 3415 spin_unlock(&cur_trans->dirty_bgs_lock);
3415 3416
3416again: 3417again:
3417 if (list_empty(&dirty)) {
3418 btrfs_free_path(path);
3419 return 0;
3420 }
3421
3422 /* 3418 /*
3423 * make sure all the block groups on our dirty list actually 3419 * make sure all the block groups on our dirty list actually
3424 * exist 3420 * exist
@@ -3431,18 +3427,16 @@ again:
3431 return -ENOMEM; 3427 return -ENOMEM;
3432 } 3428 }
3433 3429
3430 /*
3431 * cache_write_mutex is here only to save us from balance or automatic
3432 * removal of empty block groups deleting this block group while we are
3433 * writing out the cache
3434 */
3435 mutex_lock(&trans->transaction->cache_write_mutex);
3434 while (!list_empty(&dirty)) { 3436 while (!list_empty(&dirty)) {
3435 cache = list_first_entry(&dirty, 3437 cache = list_first_entry(&dirty,
3436 struct btrfs_block_group_cache, 3438 struct btrfs_block_group_cache,
3437 dirty_list); 3439 dirty_list);
3438
3439 /*
3440 * cache_write_mutex is here only to save us from balance
3441 * deleting this block group while we are writing out the
3442 * cache
3443 */
3444 mutex_lock(&trans->transaction->cache_write_mutex);
3445
3446 /* 3440 /*
3447 * this can happen if something re-dirties a block 3441 * this can happen if something re-dirties a block
3448 * group that is already under IO. Just wait for it to 3442 * group that is already under IO. Just wait for it to
@@ -3495,7 +3489,6 @@ again:
3495 } 3489 }
3496 if (!ret) 3490 if (!ret)
3497 ret = write_one_cache_group(trans, root, path, cache); 3491 ret = write_one_cache_group(trans, root, path, cache);
3498 mutex_unlock(&trans->transaction->cache_write_mutex);
3499 3492
3500 /* if its not on the io list, we need to put the block group */ 3493 /* if its not on the io list, we need to put the block group */
3501 if (should_put) 3494 if (should_put)
@@ -3503,7 +3496,16 @@ again:
3503 3496
3504 if (ret) 3497 if (ret)
3505 break; 3498 break;
3499
3500 /*
3501 * Avoid blocking other tasks for too long. It might even save
3502 * us from writing caches for block groups that are going to be
3503 * removed.
3504 */
3505 mutex_unlock(&trans->transaction->cache_write_mutex);
3506 mutex_lock(&trans->transaction->cache_write_mutex);
3506 } 3507 }
3508 mutex_unlock(&trans->transaction->cache_write_mutex);
3507 3509
3508 /* 3510 /*
3509 * go through delayed refs for all the stuff we've just kicked off 3511 * go through delayed refs for all the stuff we've just kicked off
@@ -3514,8 +3516,15 @@ again:
3514 loops++; 3516 loops++;
3515 spin_lock(&cur_trans->dirty_bgs_lock); 3517 spin_lock(&cur_trans->dirty_bgs_lock);
3516 list_splice_init(&cur_trans->dirty_bgs, &dirty); 3518 list_splice_init(&cur_trans->dirty_bgs, &dirty);
3519 /*
3520 * dirty_bgs_lock protects us from concurrent block group
3521 * deletes too (not just cache_write_mutex).
3522 */
3523 if (!list_empty(&dirty)) {
3524 spin_unlock(&cur_trans->dirty_bgs_lock);
3525 goto again;
3526 }
3517 spin_unlock(&cur_trans->dirty_bgs_lock); 3527 spin_unlock(&cur_trans->dirty_bgs_lock);
3518 goto again;
3519 } 3528 }
3520 3529
3521 btrfs_free_path(path); 3530 btrfs_free_path(path);
@@ -7537,7 +7546,7 @@ static void unuse_block_rsv(struct btrfs_fs_info *fs_info,
7537 * returns the key for the extent through ins, and a tree buffer for 7546 * returns the key for the extent through ins, and a tree buffer for
7538 * the first block of the extent through buf. 7547 * the first block of the extent through buf.
7539 * 7548 *
7540 * returns the tree buffer or NULL. 7549 * returns the tree buffer or an ERR_PTR on error.
7541 */ 7550 */
7542struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans, 7551struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
7543 struct btrfs_root *root, 7552 struct btrfs_root *root,
@@ -7548,6 +7557,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
7548 struct btrfs_key ins; 7557 struct btrfs_key ins;
7549 struct btrfs_block_rsv *block_rsv; 7558 struct btrfs_block_rsv *block_rsv;
7550 struct extent_buffer *buf; 7559 struct extent_buffer *buf;
7560 struct btrfs_delayed_extent_op *extent_op;
7551 u64 flags = 0; 7561 u64 flags = 0;
7552 int ret; 7562 int ret;
7553 u32 blocksize = root->nodesize; 7563 u32 blocksize = root->nodesize;
@@ -7568,13 +7578,14 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
7568 7578
7569 ret = btrfs_reserve_extent(root, blocksize, blocksize, 7579 ret = btrfs_reserve_extent(root, blocksize, blocksize,
7570 empty_size, hint, &ins, 0, 0); 7580 empty_size, hint, &ins, 0, 0);
7571 if (ret) { 7581 if (ret)
7572 unuse_block_rsv(root->fs_info, block_rsv, blocksize); 7582 goto out_unuse;
7573 return ERR_PTR(ret);
7574 }
7575 7583
7576 buf = btrfs_init_new_buffer(trans, root, ins.objectid, level); 7584 buf = btrfs_init_new_buffer(trans, root, ins.objectid, level);
7577 BUG_ON(IS_ERR(buf)); /* -ENOMEM */ 7585 if (IS_ERR(buf)) {
7586 ret = PTR_ERR(buf);
7587 goto out_free_reserved;
7588 }
7578 7589
7579 if (root_objectid == BTRFS_TREE_RELOC_OBJECTID) { 7590 if (root_objectid == BTRFS_TREE_RELOC_OBJECTID) {
7580 if (parent == 0) 7591 if (parent == 0)
@@ -7584,9 +7595,11 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
7584 BUG_ON(parent > 0); 7595 BUG_ON(parent > 0);
7585 7596
7586 if (root_objectid != BTRFS_TREE_LOG_OBJECTID) { 7597 if (root_objectid != BTRFS_TREE_LOG_OBJECTID) {
7587 struct btrfs_delayed_extent_op *extent_op;
7588 extent_op = btrfs_alloc_delayed_extent_op(); 7598 extent_op = btrfs_alloc_delayed_extent_op();
7589 BUG_ON(!extent_op); /* -ENOMEM */ 7599 if (!extent_op) {
7600 ret = -ENOMEM;
7601 goto out_free_buf;
7602 }
7590 if (key) 7603 if (key)
7591 memcpy(&extent_op->key, key, sizeof(extent_op->key)); 7604 memcpy(&extent_op->key, key, sizeof(extent_op->key));
7592 else 7605 else
@@ -7601,13 +7614,24 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
7601 extent_op->level = level; 7614 extent_op->level = level;
7602 7615
7603 ret = btrfs_add_delayed_tree_ref(root->fs_info, trans, 7616 ret = btrfs_add_delayed_tree_ref(root->fs_info, trans,
7604 ins.objectid, 7617 ins.objectid, ins.offset,
7605 ins.offset, parent, root_objectid, 7618 parent, root_objectid, level,
7606 level, BTRFS_ADD_DELAYED_EXTENT, 7619 BTRFS_ADD_DELAYED_EXTENT,
7607 extent_op, 0); 7620 extent_op, 0);
7608 BUG_ON(ret); /* -ENOMEM */ 7621 if (ret)
7622 goto out_free_delayed;
7609 } 7623 }
7610 return buf; 7624 return buf;
7625
7626out_free_delayed:
7627 btrfs_free_delayed_extent_op(extent_op);
7628out_free_buf:
7629 free_extent_buffer(buf);
7630out_free_reserved:
7631 btrfs_free_reserved_extent(root, ins.objectid, ins.offset, 0);
7632out_unuse:
7633 unuse_block_rsv(root->fs_info, block_rsv, blocksize);
7634 return ERR_PTR(ret);
7611} 7635}
7612 7636
7613struct walk_control { 7637struct walk_control {