aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/extent-tree.c86
1 files changed, 67 insertions, 19 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 01c1f08b976a..5b84205e7685 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3334,12 +3334,12 @@ out:
3334/* 3334/*
3335 * shrink metadata reservation for delalloc 3335 * shrink metadata reservation for delalloc
3336 */ 3336 */
3337static int shrink_delalloc(struct btrfs_trans_handle *trans, 3337static int shrink_delalloc(struct btrfs_root *root, u64 to_reclaim,
3338 struct btrfs_root *root, u64 to_reclaim,
3339 bool wait_ordered) 3338 bool wait_ordered)
3340{ 3339{
3341 struct btrfs_block_rsv *block_rsv; 3340 struct btrfs_block_rsv *block_rsv;
3342 struct btrfs_space_info *space_info; 3341 struct btrfs_space_info *space_info;
3342 struct btrfs_trans_handle *trans;
3343 u64 reserved; 3343 u64 reserved;
3344 u64 max_reclaim; 3344 u64 max_reclaim;
3345 u64 reclaimed = 0; 3345 u64 reclaimed = 0;
@@ -3348,6 +3348,7 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
3348 int loops = 0; 3348 int loops = 0;
3349 unsigned long progress; 3349 unsigned long progress;
3350 3350
3351 trans = (struct btrfs_trans_handle *)current->journal_info;
3351 block_rsv = &root->fs_info->delalloc_block_rsv; 3352 block_rsv = &root->fs_info->delalloc_block_rsv;
3352 space_info = block_rsv->space_info; 3353 space_info = block_rsv->space_info;
3353 3354
@@ -3418,6 +3419,60 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
3418} 3419}
3419 3420
3420/** 3421/**
3422 * maybe_commit_transaction - possibly commit the transaction if its ok to
3423 * @root - the root we're allocating for
3424 * @bytes - the number of bytes we want to reserve
3425 * @force - force the commit
3426 *
3427 * This will check to make sure that committing the transaction will actually
3428 * get us somewhere and then commit the transaction if it does. Otherwise it
3429 * will return -ENOSPC.
3430 */
3431static int may_commit_transaction(struct btrfs_root *root,
3432 struct btrfs_space_info *space_info,
3433 u64 bytes, int force)
3434{
3435 struct btrfs_block_rsv *delayed_rsv = &root->fs_info->delayed_block_rsv;
3436 struct btrfs_trans_handle *trans;
3437
3438 trans = (struct btrfs_trans_handle *)current->journal_info;
3439 if (trans)
3440 return -EAGAIN;
3441
3442 if (force)
3443 goto commit;
3444
3445 /* See if there is enough pinned space to make this reservation */
3446 spin_lock(&space_info->lock);
3447 if (space_info->bytes_pinned >= bytes) {
3448 spin_unlock(&space_info->lock);
3449 goto commit;
3450 }
3451 spin_unlock(&space_info->lock);
3452
3453 /*
3454 * See if there is some space in the delayed insertion reservation for
3455 * this reservation.
3456 */
3457 if (space_info != delayed_rsv->space_info)
3458 return -ENOSPC;
3459
3460 spin_lock(&delayed_rsv->lock);
3461 if (delayed_rsv->size < bytes) {
3462 spin_unlock(&delayed_rsv->lock);
3463 return -ENOSPC;
3464 }
3465 spin_unlock(&delayed_rsv->lock);
3466
3467commit:
3468 trans = btrfs_join_transaction(root);
3469 if (IS_ERR(trans))
3470 return -ENOSPC;
3471
3472 return btrfs_commit_transaction(trans, root);
3473}
3474
3475/**
3421 * reserve_metadata_bytes - try to reserve bytes from the block_rsv's space 3476 * reserve_metadata_bytes - try to reserve bytes from the block_rsv's space
3422 * @root - the root we're allocating for 3477 * @root - the root we're allocating for
3423 * @block_rsv - the block_rsv we're allocating for 3478 * @block_rsv - the block_rsv we're allocating for
@@ -3436,7 +3491,6 @@ static int reserve_metadata_bytes(struct btrfs_root *root,
3436 u64 orig_bytes, int flush) 3491 u64 orig_bytes, int flush)
3437{ 3492{
3438 struct btrfs_space_info *space_info = block_rsv->space_info; 3493 struct btrfs_space_info *space_info = block_rsv->space_info;
3439 struct btrfs_trans_handle *trans;
3440 u64 used; 3494 u64 used;
3441 u64 num_bytes = orig_bytes; 3495 u64 num_bytes = orig_bytes;
3442 int retries = 0; 3496 int retries = 0;
@@ -3445,7 +3499,6 @@ static int reserve_metadata_bytes(struct btrfs_root *root,
3445 bool flushing = false; 3499 bool flushing = false;
3446 bool wait_ordered = false; 3500 bool wait_ordered = false;
3447 3501
3448 trans = (struct btrfs_trans_handle *)current->journal_info;
3449again: 3502again:
3450 ret = 0; 3503 ret = 0;
3451 spin_lock(&space_info->lock); 3504 spin_lock(&space_info->lock);
@@ -3461,7 +3514,7 @@ again:
3461 * deadlock since we are waiting for the flusher to finish, but 3514 * deadlock since we are waiting for the flusher to finish, but
3462 * hold the current transaction open. 3515 * hold the current transaction open.
3463 */ 3516 */
3464 if (trans) 3517 if (current->journal_info)
3465 return -EAGAIN; 3518 return -EAGAIN;
3466 ret = wait_event_interruptible(space_info->wait, 3519 ret = wait_event_interruptible(space_info->wait,
3467 !space_info->flush); 3520 !space_info->flush);
@@ -3517,12 +3570,16 @@ again:
3517 */ 3570 */
3518 avail = (space_info->total_bytes - space_info->bytes_used) * 8; 3571 avail = (space_info->total_bytes - space_info->bytes_used) * 8;
3519 do_div(avail, 10); 3572 do_div(avail, 10);
3520 if (space_info->bytes_pinned >= avail && flush && !trans && 3573 if (space_info->bytes_pinned >= avail && flush && !committed) {
3521 !committed) {
3522 space_info->flush = 1; 3574 space_info->flush = 1;
3523 flushing = true; 3575 flushing = true;
3524 spin_unlock(&space_info->lock); 3576 spin_unlock(&space_info->lock);
3525 goto commit; 3577 ret = may_commit_transaction(root, space_info,
3578 orig_bytes, 1);
3579 if (ret)
3580 goto out;
3581 committed = true;
3582 goto again;
3526 } 3583 }
3527 3584
3528 spin_lock(&root->fs_info->free_chunk_lock); 3585 spin_lock(&root->fs_info->free_chunk_lock);
@@ -3575,7 +3632,7 @@ again:
3575 * We do synchronous shrinking since we don't actually unreserve 3632 * We do synchronous shrinking since we don't actually unreserve
3576 * metadata until after the IO is completed. 3633 * metadata until after the IO is completed.
3577 */ 3634 */
3578 ret = shrink_delalloc(trans, root, num_bytes, wait_ordered); 3635 ret = shrink_delalloc(root, num_bytes, wait_ordered);
3579 if (ret < 0) 3636 if (ret < 0)
3580 goto out; 3637 goto out;
3581 3638
@@ -3592,21 +3649,12 @@ again:
3592 goto again; 3649 goto again;
3593 } 3650 }
3594 3651
3595 ret = -EAGAIN;
3596 if (trans)
3597 goto out;
3598
3599commit:
3600 ret = -ENOSPC; 3652 ret = -ENOSPC;
3601 if (committed) 3653 if (committed)
3602 goto out; 3654 goto out;
3603 3655
3604 trans = btrfs_join_transaction(root); 3656 ret = may_commit_transaction(root, space_info, orig_bytes, 0);
3605 if (IS_ERR(trans))
3606 goto out;
3607 ret = btrfs_commit_transaction(trans, root);
3608 if (!ret) { 3657 if (!ret) {
3609 trans = NULL;
3610 committed = true; 3658 committed = true;
3611 goto again; 3659 goto again;
3612 } 3660 }