diff options
author | Chris Mason <chris.mason@oracle.com> | 2010-10-29 09:27:49 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2010-10-29 09:27:49 -0400 |
commit | 6b5b817f103450444f3f658a498f435d92a197e5 (patch) | |
tree | 2896588127c4dd6c2867ef09e7e3cdd83391f8ae /fs/btrfs/extent-tree.c | |
parent | 8216ef866df1119fd5a72372b8b29bce49c18590 (diff) | |
parent | e9bb7f10d3617304ef94ff7aa8fefbce3078f08b (diff) |
Merge branch 'bug-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/josef/btrfs-work
Conflicts:
fs/btrfs/extent-tree.c
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 298 |
1 files changed, 171 insertions, 127 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index d2a7ff53e99a..372fd224a11d 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -2976,6 +2976,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, | |||
2976 | if (found) { | 2976 | if (found) { |
2977 | spin_lock(&found->lock); | 2977 | spin_lock(&found->lock); |
2978 | found->total_bytes += total_bytes; | 2978 | found->total_bytes += total_bytes; |
2979 | found->disk_total += total_bytes * factor; | ||
2979 | found->bytes_used += bytes_used; | 2980 | found->bytes_used += bytes_used; |
2980 | found->disk_used += bytes_used * factor; | 2981 | found->disk_used += bytes_used * factor; |
2981 | found->full = 0; | 2982 | found->full = 0; |
@@ -2995,6 +2996,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, | |||
2995 | BTRFS_BLOCK_GROUP_SYSTEM | | 2996 | BTRFS_BLOCK_GROUP_SYSTEM | |
2996 | BTRFS_BLOCK_GROUP_METADATA); | 2997 | BTRFS_BLOCK_GROUP_METADATA); |
2997 | found->total_bytes = total_bytes; | 2998 | found->total_bytes = total_bytes; |
2999 | found->disk_total = total_bytes * factor; | ||
2998 | found->bytes_used = bytes_used; | 3000 | found->bytes_used = bytes_used; |
2999 | found->disk_used = bytes_used * factor; | 3001 | found->disk_used = bytes_used * factor; |
3000 | found->bytes_pinned = 0; | 3002 | found->bytes_pinned = 0; |
@@ -3216,8 +3218,7 @@ static void force_metadata_allocation(struct btrfs_fs_info *info) | |||
3216 | rcu_read_unlock(); | 3218 | rcu_read_unlock(); |
3217 | } | 3219 | } |
3218 | 3220 | ||
3219 | static int should_alloc_chunk(struct btrfs_space_info *sinfo, | 3221 | static int should_alloc_chunk(struct btrfs_space_info *sinfo, u64 alloc_bytes) |
3220 | u64 alloc_bytes) | ||
3221 | { | 3222 | { |
3222 | u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly; | 3223 | u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly; |
3223 | 3224 | ||
@@ -3229,6 +3230,10 @@ static int should_alloc_chunk(struct btrfs_space_info *sinfo, | |||
3229 | alloc_bytes < div_factor(num_bytes, 8)) | 3230 | alloc_bytes < div_factor(num_bytes, 8)) |
3230 | return 0; | 3231 | return 0; |
3231 | 3232 | ||
3233 | if (num_bytes > 256 * 1024 * 1024 && | ||
3234 | sinfo->bytes_used < div_factor(num_bytes, 3)) | ||
3235 | return 0; | ||
3236 | |||
3232 | return 1; | 3237 | return 1; |
3233 | } | 3238 | } |
3234 | 3239 | ||
@@ -3298,55 +3303,26 @@ out: | |||
3298 | return ret; | 3303 | return ret; |
3299 | } | 3304 | } |
3300 | 3305 | ||
3301 | static int maybe_allocate_chunk(struct btrfs_trans_handle *trans, | ||
3302 | struct btrfs_root *root, | ||
3303 | struct btrfs_space_info *sinfo, u64 num_bytes) | ||
3304 | { | ||
3305 | int ret; | ||
3306 | int end_trans = 0; | ||
3307 | |||
3308 | if (sinfo->full) | ||
3309 | return 0; | ||
3310 | |||
3311 | spin_lock(&sinfo->lock); | ||
3312 | ret = should_alloc_chunk(sinfo, num_bytes + 2 * 1024 * 1024); | ||
3313 | spin_unlock(&sinfo->lock); | ||
3314 | if (!ret) | ||
3315 | return 0; | ||
3316 | |||
3317 | if (!trans) { | ||
3318 | trans = btrfs_join_transaction(root, 1); | ||
3319 | BUG_ON(IS_ERR(trans)); | ||
3320 | end_trans = 1; | ||
3321 | } | ||
3322 | |||
3323 | ret = do_chunk_alloc(trans, root->fs_info->extent_root, | ||
3324 | num_bytes + 2 * 1024 * 1024, | ||
3325 | get_alloc_profile(root, sinfo->flags), 0); | ||
3326 | |||
3327 | if (end_trans) | ||
3328 | btrfs_end_transaction(trans, root); | ||
3329 | |||
3330 | return ret == 1 ? 1 : 0; | ||
3331 | } | ||
3332 | |||
3333 | /* | 3306 | /* |
3334 | * shrink metadata reservation for delalloc | 3307 | * shrink metadata reservation for delalloc |
3335 | */ | 3308 | */ |
3336 | static int shrink_delalloc(struct btrfs_trans_handle *trans, | 3309 | static int shrink_delalloc(struct btrfs_trans_handle *trans, |
3337 | struct btrfs_root *root, u64 to_reclaim) | 3310 | struct btrfs_root *root, u64 to_reclaim, int sync) |
3338 | { | 3311 | { |
3339 | struct btrfs_block_rsv *block_rsv; | 3312 | struct btrfs_block_rsv *block_rsv; |
3313 | struct btrfs_space_info *space_info; | ||
3340 | u64 reserved; | 3314 | u64 reserved; |
3341 | u64 max_reclaim; | 3315 | u64 max_reclaim; |
3342 | u64 reclaimed = 0; | 3316 | u64 reclaimed = 0; |
3317 | int no_reclaim = 0; | ||
3343 | int pause = 1; | 3318 | int pause = 1; |
3344 | int ret; | 3319 | int ret; |
3345 | 3320 | ||
3346 | block_rsv = &root->fs_info->delalloc_block_rsv; | 3321 | block_rsv = &root->fs_info->delalloc_block_rsv; |
3347 | spin_lock(&block_rsv->lock); | 3322 | space_info = block_rsv->space_info; |
3348 | reserved = block_rsv->reserved; | 3323 | spin_lock(&space_info->lock); |
3349 | spin_unlock(&block_rsv->lock); | 3324 | reserved = space_info->bytes_reserved; |
3325 | spin_unlock(&space_info->lock); | ||
3350 | 3326 | ||
3351 | if (reserved == 0) | 3327 | if (reserved == 0) |
3352 | return 0; | 3328 | return 0; |
@@ -3354,22 +3330,26 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
3354 | max_reclaim = min(reserved, to_reclaim); | 3330 | max_reclaim = min(reserved, to_reclaim); |
3355 | 3331 | ||
3356 | while (1) { | 3332 | while (1) { |
3357 | ret = btrfs_start_one_delalloc_inode(root, trans ? 1 : 0); | 3333 | ret = btrfs_start_one_delalloc_inode(root, trans ? 1 : 0, sync); |
3358 | if (!ret) { | 3334 | if (!ret) { |
3335 | if (no_reclaim > 2) | ||
3336 | break; | ||
3337 | no_reclaim++; | ||
3359 | __set_current_state(TASK_INTERRUPTIBLE); | 3338 | __set_current_state(TASK_INTERRUPTIBLE); |
3360 | schedule_timeout(pause); | 3339 | schedule_timeout(pause); |
3361 | pause <<= 1; | 3340 | pause <<= 1; |
3362 | if (pause > HZ / 10) | 3341 | if (pause > HZ / 10) |
3363 | pause = HZ / 10; | 3342 | pause = HZ / 10; |
3364 | } else { | 3343 | } else { |
3344 | no_reclaim = 0; | ||
3365 | pause = 1; | 3345 | pause = 1; |
3366 | } | 3346 | } |
3367 | 3347 | ||
3368 | spin_lock(&block_rsv->lock); | 3348 | spin_lock(&space_info->lock); |
3369 | if (reserved > block_rsv->reserved) | 3349 | if (reserved > space_info->bytes_reserved) |
3370 | reclaimed = reserved - block_rsv->reserved; | 3350 | reclaimed += reserved - space_info->bytes_reserved; |
3371 | reserved = block_rsv->reserved; | 3351 | reserved = space_info->bytes_reserved; |
3372 | spin_unlock(&block_rsv->lock); | 3352 | spin_unlock(&space_info->lock); |
3373 | 3353 | ||
3374 | if (reserved == 0 || reclaimed >= max_reclaim) | 3354 | if (reserved == 0 || reclaimed >= max_reclaim) |
3375 | break; | 3355 | break; |
@@ -3380,78 +3360,141 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans, | |||
3380 | return reclaimed >= to_reclaim; | 3360 | return reclaimed >= to_reclaim; |
3381 | } | 3361 | } |
3382 | 3362 | ||
3383 | static int should_retry_reserve(struct btrfs_trans_handle *trans, | 3363 | /* |
3384 | struct btrfs_root *root, | 3364 | * Retries tells us how many times we've called reserve_metadata_bytes. The |
3385 | struct btrfs_block_rsv *block_rsv, | 3365 | * idea is if this is the first call (retries == 0) then we will add to our |
3386 | u64 num_bytes, int *retries) | 3366 | * reserved count if we can't make the allocation in order to hold our place |
3367 | * while we go and try and free up space. That way for retries > 1 we don't try | ||
3368 | * and add space, we just check to see if the amount of unused space is >= the | ||
3369 | * total space, meaning that our reservation is valid. | ||
3370 | * | ||
3371 | * However if we don't intend to retry this reservation, pass -1 as retries so | ||
3372 | * that it short circuits this logic. | ||
3373 | */ | ||
3374 | static int reserve_metadata_bytes(struct btrfs_trans_handle *trans, | ||
3375 | struct btrfs_root *root, | ||
3376 | struct btrfs_block_rsv *block_rsv, | ||
3377 | u64 orig_bytes, int flush) | ||
3387 | { | 3378 | { |
3388 | struct btrfs_space_info *space_info = block_rsv->space_info; | 3379 | struct btrfs_space_info *space_info = block_rsv->space_info; |
3389 | int ret; | 3380 | u64 unused; |
3381 | u64 num_bytes = orig_bytes; | ||
3382 | int retries = 0; | ||
3383 | int ret = 0; | ||
3384 | bool reserved = false; | ||
3385 | bool committed = false; | ||
3390 | 3386 | ||
3391 | if ((*retries) > 2) | 3387 | again: |
3392 | return -ENOSPC; | 3388 | ret = -ENOSPC; |
3389 | if (reserved) | ||
3390 | num_bytes = 0; | ||
3393 | 3391 | ||
3394 | ret = maybe_allocate_chunk(trans, root, space_info, num_bytes); | 3392 | spin_lock(&space_info->lock); |
3395 | if (ret) | 3393 | unused = space_info->bytes_used + space_info->bytes_reserved + |
3396 | return 1; | 3394 | space_info->bytes_pinned + space_info->bytes_readonly + |
3395 | space_info->bytes_may_use; | ||
3397 | 3396 | ||
3398 | if (trans && trans->transaction->in_commit) | 3397 | /* |
3399 | return -ENOSPC; | 3398 | * The idea here is that we've not already over-reserved the block group |
3399 | * then we can go ahead and save our reservation first and then start | ||
3400 | * flushing if we need to. Otherwise if we've already overcommitted | ||
3401 | * lets start flushing stuff first and then come back and try to make | ||
3402 | * our reservation. | ||
3403 | */ | ||
3404 | if (unused <= space_info->total_bytes) { | ||
3405 | unused -= space_info->total_bytes; | ||
3406 | if (unused >= num_bytes) { | ||
3407 | if (!reserved) | ||
3408 | space_info->bytes_reserved += orig_bytes; | ||
3409 | ret = 0; | ||
3410 | } else { | ||
3411 | /* | ||
3412 | * Ok set num_bytes to orig_bytes since we aren't | ||
3413 | * overocmmitted, this way we only try and reclaim what | ||
3414 | * we need. | ||
3415 | */ | ||
3416 | num_bytes = orig_bytes; | ||
3417 | } | ||
3418 | } else { | ||
3419 | /* | ||
3420 | * Ok we're over committed, set num_bytes to the overcommitted | ||
3421 | * amount plus the amount of bytes that we need for this | ||
3422 | * reservation. | ||
3423 | */ | ||
3424 | num_bytes = unused - space_info->total_bytes + | ||
3425 | (orig_bytes * (retries + 1)); | ||
3426 | } | ||
3400 | 3427 | ||
3401 | ret = shrink_delalloc(trans, root, num_bytes); | 3428 | /* |
3402 | if (ret) | 3429 | * Couldn't make our reservation, save our place so while we're trying |
3403 | return ret; | 3430 | * to reclaim space we can actually use it instead of somebody else |
3431 | * stealing it from us. | ||
3432 | */ | ||
3433 | if (ret && !reserved) { | ||
3434 | space_info->bytes_reserved += orig_bytes; | ||
3435 | reserved = true; | ||
3436 | } | ||
3404 | 3437 | ||
3405 | spin_lock(&space_info->lock); | ||
3406 | if (space_info->bytes_pinned < num_bytes) | ||
3407 | ret = 1; | ||
3408 | spin_unlock(&space_info->lock); | 3438 | spin_unlock(&space_info->lock); |
3409 | if (ret) | ||
3410 | return -ENOSPC; | ||
3411 | 3439 | ||
3412 | (*retries)++; | 3440 | if (!ret) |
3413 | 3441 | return 0; | |
3414 | if (trans) | ||
3415 | return -EAGAIN; | ||
3416 | 3442 | ||
3417 | trans = btrfs_join_transaction(root, 1); | 3443 | if (!flush) |
3418 | BUG_ON(IS_ERR(trans)); | 3444 | goto out; |
3419 | ret = btrfs_commit_transaction(trans, root); | ||
3420 | BUG_ON(ret); | ||
3421 | 3445 | ||
3422 | return 1; | 3446 | /* |
3423 | } | 3447 | * We do synchronous shrinking since we don't actually unreserve |
3448 | * metadata until after the IO is completed. | ||
3449 | */ | ||
3450 | ret = shrink_delalloc(trans, root, num_bytes, 1); | ||
3451 | if (ret > 0) | ||
3452 | return 0; | ||
3453 | else if (ret < 0) | ||
3454 | goto out; | ||
3424 | 3455 | ||
3425 | static int reserve_metadata_bytes(struct btrfs_block_rsv *block_rsv, | 3456 | /* |
3426 | u64 num_bytes) | 3457 | * So if we were overcommitted it's possible that somebody else flushed |
3427 | { | 3458 | * out enough space and we simply didn't have enough space to reclaim, |
3428 | struct btrfs_space_info *space_info = block_rsv->space_info; | 3459 | * so go back around and try again. |
3429 | u64 unused; | 3460 | */ |
3430 | int ret = -ENOSPC; | 3461 | if (retries < 2) { |
3462 | retries++; | ||
3463 | goto again; | ||
3464 | } | ||
3431 | 3465 | ||
3432 | spin_lock(&space_info->lock); | 3466 | spin_lock(&space_info->lock); |
3433 | unused = space_info->bytes_used + space_info->bytes_reserved + | 3467 | /* |
3434 | space_info->bytes_pinned + space_info->bytes_readonly; | 3468 | * Not enough space to be reclaimed, don't bother committing the |
3469 | * transaction. | ||
3470 | */ | ||
3471 | if (space_info->bytes_pinned < orig_bytes) | ||
3472 | ret = -ENOSPC; | ||
3473 | spin_unlock(&space_info->lock); | ||
3474 | if (ret) | ||
3475 | goto out; | ||
3435 | 3476 | ||
3436 | if (unused < space_info->total_bytes) | 3477 | ret = -EAGAIN; |
3437 | unused = space_info->total_bytes - unused; | 3478 | if (trans || committed) |
3438 | else | 3479 | goto out; |
3439 | unused = 0; | ||
3440 | 3480 | ||
3441 | if (unused >= num_bytes) { | 3481 | ret = -ENOSPC; |
3442 | if (block_rsv->priority >= 10) { | 3482 | trans = btrfs_join_transaction(root, 1); |
3443 | space_info->bytes_reserved += num_bytes; | 3483 | if (IS_ERR(trans)) |
3444 | ret = 0; | 3484 | goto out; |
3445 | } else { | 3485 | ret = btrfs_commit_transaction(trans, root); |
3446 | if ((unused + block_rsv->reserved) * | 3486 | if (!ret) { |
3447 | block_rsv->priority >= | 3487 | trans = NULL; |
3448 | (num_bytes + block_rsv->reserved) * 10) { | 3488 | committed = true; |
3449 | space_info->bytes_reserved += num_bytes; | 3489 | goto again; |
3450 | ret = 0; | 3490 | } |
3451 | } | 3491 | |
3452 | } | 3492 | out: |
3493 | if (reserved) { | ||
3494 | spin_lock(&space_info->lock); | ||
3495 | space_info->bytes_reserved -= orig_bytes; | ||
3496 | spin_unlock(&space_info->lock); | ||
3453 | } | 3497 | } |
3454 | spin_unlock(&space_info->lock); | ||
3455 | 3498 | ||
3456 | return ret; | 3499 | return ret; |
3457 | } | 3500 | } |
@@ -3595,23 +3638,19 @@ void btrfs_add_durable_block_rsv(struct btrfs_fs_info *fs_info, | |||
3595 | int btrfs_block_rsv_add(struct btrfs_trans_handle *trans, | 3638 | int btrfs_block_rsv_add(struct btrfs_trans_handle *trans, |
3596 | struct btrfs_root *root, | 3639 | struct btrfs_root *root, |
3597 | struct btrfs_block_rsv *block_rsv, | 3640 | struct btrfs_block_rsv *block_rsv, |
3598 | u64 num_bytes, int *retries) | 3641 | u64 num_bytes) |
3599 | { | 3642 | { |
3600 | int ret; | 3643 | int ret; |
3601 | 3644 | ||
3602 | if (num_bytes == 0) | 3645 | if (num_bytes == 0) |
3603 | return 0; | 3646 | return 0; |
3604 | again: | 3647 | |
3605 | ret = reserve_metadata_bytes(block_rsv, num_bytes); | 3648 | ret = reserve_metadata_bytes(trans, root, block_rsv, num_bytes, 1); |
3606 | if (!ret) { | 3649 | if (!ret) { |
3607 | block_rsv_add_bytes(block_rsv, num_bytes, 1); | 3650 | block_rsv_add_bytes(block_rsv, num_bytes, 1); |
3608 | return 0; | 3651 | return 0; |
3609 | } | 3652 | } |
3610 | 3653 | ||
3611 | ret = should_retry_reserve(trans, root, block_rsv, num_bytes, retries); | ||
3612 | if (ret > 0) | ||
3613 | goto again; | ||
3614 | |||
3615 | return ret; | 3654 | return ret; |
3616 | } | 3655 | } |
3617 | 3656 | ||
@@ -3646,7 +3685,8 @@ int btrfs_block_rsv_check(struct btrfs_trans_handle *trans, | |||
3646 | return 0; | 3685 | return 0; |
3647 | 3686 | ||
3648 | if (block_rsv->refill_used) { | 3687 | if (block_rsv->refill_used) { |
3649 | ret = reserve_metadata_bytes(block_rsv, num_bytes); | 3688 | ret = reserve_metadata_bytes(trans, root, block_rsv, |
3689 | num_bytes, 0); | ||
3650 | if (!ret) { | 3690 | if (!ret) { |
3651 | block_rsv_add_bytes(block_rsv, num_bytes, 0); | 3691 | block_rsv_add_bytes(block_rsv, num_bytes, 0); |
3652 | return 0; | 3692 | return 0; |
@@ -3725,6 +3765,8 @@ static u64 calc_global_metadata_size(struct btrfs_fs_info *fs_info) | |||
3725 | 3765 | ||
3726 | sinfo = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA); | 3766 | sinfo = __find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA); |
3727 | spin_lock(&sinfo->lock); | 3767 | spin_lock(&sinfo->lock); |
3768 | if (sinfo->flags & BTRFS_BLOCK_GROUP_DATA) | ||
3769 | data_used = 0; | ||
3728 | meta_used = sinfo->bytes_used; | 3770 | meta_used = sinfo->bytes_used; |
3729 | spin_unlock(&sinfo->lock); | 3771 | spin_unlock(&sinfo->lock); |
3730 | 3772 | ||
@@ -3752,7 +3794,8 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info) | |||
3752 | block_rsv->size = num_bytes; | 3794 | block_rsv->size = num_bytes; |
3753 | 3795 | ||
3754 | num_bytes = sinfo->bytes_used + sinfo->bytes_pinned + | 3796 | num_bytes = sinfo->bytes_used + sinfo->bytes_pinned + |
3755 | sinfo->bytes_reserved + sinfo->bytes_readonly; | 3797 | sinfo->bytes_reserved + sinfo->bytes_readonly + |
3798 | sinfo->bytes_may_use; | ||
3756 | 3799 | ||
3757 | if (sinfo->total_bytes > num_bytes) { | 3800 | if (sinfo->total_bytes > num_bytes) { |
3758 | num_bytes = sinfo->total_bytes - num_bytes; | 3801 | num_bytes = sinfo->total_bytes - num_bytes; |
@@ -3823,7 +3866,7 @@ static u64 calc_trans_metadata_size(struct btrfs_root *root, int num_items) | |||
3823 | 3866 | ||
3824 | int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans, | 3867 | int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans, |
3825 | struct btrfs_root *root, | 3868 | struct btrfs_root *root, |
3826 | int num_items, int *retries) | 3869 | int num_items) |
3827 | { | 3870 | { |
3828 | u64 num_bytes; | 3871 | u64 num_bytes; |
3829 | int ret; | 3872 | int ret; |
@@ -3833,7 +3876,7 @@ int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans, | |||
3833 | 3876 | ||
3834 | num_bytes = calc_trans_metadata_size(root, num_items); | 3877 | num_bytes = calc_trans_metadata_size(root, num_items); |
3835 | ret = btrfs_block_rsv_add(trans, root, &root->fs_info->trans_block_rsv, | 3878 | ret = btrfs_block_rsv_add(trans, root, &root->fs_info->trans_block_rsv, |
3836 | num_bytes, retries); | 3879 | num_bytes); |
3837 | if (!ret) { | 3880 | if (!ret) { |
3838 | trans->bytes_reserved += num_bytes; | 3881 | trans->bytes_reserved += num_bytes; |
3839 | trans->block_rsv = &root->fs_info->trans_block_rsv; | 3882 | trans->block_rsv = &root->fs_info->trans_block_rsv; |
@@ -3907,14 +3950,13 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes) | |||
3907 | struct btrfs_block_rsv *block_rsv = &root->fs_info->delalloc_block_rsv; | 3950 | struct btrfs_block_rsv *block_rsv = &root->fs_info->delalloc_block_rsv; |
3908 | u64 to_reserve; | 3951 | u64 to_reserve; |
3909 | int nr_extents; | 3952 | int nr_extents; |
3910 | int retries = 0; | ||
3911 | int ret; | 3953 | int ret; |
3912 | 3954 | ||
3913 | if (btrfs_transaction_in_commit(root->fs_info)) | 3955 | if (btrfs_transaction_in_commit(root->fs_info)) |
3914 | schedule_timeout(1); | 3956 | schedule_timeout(1); |
3915 | 3957 | ||
3916 | num_bytes = ALIGN(num_bytes, root->sectorsize); | 3958 | num_bytes = ALIGN(num_bytes, root->sectorsize); |
3917 | again: | 3959 | |
3918 | spin_lock(&BTRFS_I(inode)->accounting_lock); | 3960 | spin_lock(&BTRFS_I(inode)->accounting_lock); |
3919 | nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents) + 1; | 3961 | nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents) + 1; |
3920 | if (nr_extents > BTRFS_I(inode)->reserved_extents) { | 3962 | if (nr_extents > BTRFS_I(inode)->reserved_extents) { |
@@ -3924,18 +3966,14 @@ again: | |||
3924 | nr_extents = 0; | 3966 | nr_extents = 0; |
3925 | to_reserve = 0; | 3967 | to_reserve = 0; |
3926 | } | 3968 | } |
3969 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | ||
3927 | 3970 | ||
3928 | to_reserve += calc_csum_metadata_size(inode, num_bytes); | 3971 | to_reserve += calc_csum_metadata_size(inode, num_bytes); |
3929 | ret = reserve_metadata_bytes(block_rsv, to_reserve); | 3972 | ret = reserve_metadata_bytes(NULL, root, block_rsv, to_reserve, 1); |
3930 | if (ret) { | 3973 | if (ret) |
3931 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | ||
3932 | ret = should_retry_reserve(NULL, root, block_rsv, to_reserve, | ||
3933 | &retries); | ||
3934 | if (ret > 0) | ||
3935 | goto again; | ||
3936 | return ret; | 3974 | return ret; |
3937 | } | ||
3938 | 3975 | ||
3976 | spin_lock(&BTRFS_I(inode)->accounting_lock); | ||
3939 | BTRFS_I(inode)->reserved_extents += nr_extents; | 3977 | BTRFS_I(inode)->reserved_extents += nr_extents; |
3940 | atomic_inc(&BTRFS_I(inode)->outstanding_extents); | 3978 | atomic_inc(&BTRFS_I(inode)->outstanding_extents); |
3941 | spin_unlock(&BTRFS_I(inode)->accounting_lock); | 3979 | spin_unlock(&BTRFS_I(inode)->accounting_lock); |
@@ -3943,7 +3981,7 @@ again: | |||
3943 | block_rsv_add_bytes(block_rsv, to_reserve, 1); | 3981 | block_rsv_add_bytes(block_rsv, to_reserve, 1); |
3944 | 3982 | ||
3945 | if (block_rsv->size > 512 * 1024 * 1024) | 3983 | if (block_rsv->size > 512 * 1024 * 1024) |
3946 | shrink_delalloc(NULL, root, to_reserve); | 3984 | shrink_delalloc(NULL, root, to_reserve, 0); |
3947 | 3985 | ||
3948 | return 0; | 3986 | return 0; |
3949 | } | 3987 | } |
@@ -5561,7 +5599,8 @@ use_block_rsv(struct btrfs_trans_handle *trans, | |||
5561 | block_rsv = get_block_rsv(trans, root); | 5599 | block_rsv = get_block_rsv(trans, root); |
5562 | 5600 | ||
5563 | if (block_rsv->size == 0) { | 5601 | if (block_rsv->size == 0) { |
5564 | ret = reserve_metadata_bytes(block_rsv, blocksize); | 5602 | ret = reserve_metadata_bytes(trans, root, block_rsv, |
5603 | blocksize, 0); | ||
5565 | if (ret) | 5604 | if (ret) |
5566 | return ERR_PTR(ret); | 5605 | return ERR_PTR(ret); |
5567 | return block_rsv; | 5606 | return block_rsv; |
@@ -5571,11 +5610,6 @@ use_block_rsv(struct btrfs_trans_handle *trans, | |||
5571 | if (!ret) | 5610 | if (!ret) |
5572 | return block_rsv; | 5611 | return block_rsv; |
5573 | 5612 | ||
5574 | WARN_ON(1); | ||
5575 | printk(KERN_INFO"block_rsv size %llu reserved %llu freed %llu %llu\n", | ||
5576 | block_rsv->size, block_rsv->reserved, | ||
5577 | block_rsv->freed[0], block_rsv->freed[1]); | ||
5578 | |||
5579 | return ERR_PTR(-ENOSPC); | 5613 | return ERR_PTR(-ENOSPC); |
5580 | } | 5614 | } |
5581 | 5615 | ||
@@ -8393,6 +8427,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
8393 | struct btrfs_key key; | 8427 | struct btrfs_key key; |
8394 | struct inode *inode; | 8428 | struct inode *inode; |
8395 | int ret; | 8429 | int ret; |
8430 | int factor; | ||
8396 | 8431 | ||
8397 | root = root->fs_info->extent_root; | 8432 | root = root->fs_info->extent_root; |
8398 | 8433 | ||
@@ -8400,6 +8435,14 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
8400 | BUG_ON(!block_group); | 8435 | BUG_ON(!block_group); |
8401 | BUG_ON(!block_group->ro); | 8436 | BUG_ON(!block_group->ro); |
8402 | 8437 | ||
8438 | memcpy(&key, &block_group->key, sizeof(key)); | ||
8439 | if (block_group->flags & (BTRFS_BLOCK_GROUP_DUP | | ||
8440 | BTRFS_BLOCK_GROUP_RAID1 | | ||
8441 | BTRFS_BLOCK_GROUP_RAID10)) | ||
8442 | factor = 2; | ||
8443 | else | ||
8444 | factor = 1; | ||
8445 | |||
8403 | /* make sure this block group isn't part of an allocation cluster */ | 8446 | /* make sure this block group isn't part of an allocation cluster */ |
8404 | cluster = &root->fs_info->data_alloc_cluster; | 8447 | cluster = &root->fs_info->data_alloc_cluster; |
8405 | spin_lock(&cluster->refill_lock); | 8448 | spin_lock(&cluster->refill_lock); |
@@ -8473,6 +8516,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
8473 | spin_lock(&block_group->space_info->lock); | 8516 | spin_lock(&block_group->space_info->lock); |
8474 | block_group->space_info->total_bytes -= block_group->key.offset; | 8517 | block_group->space_info->total_bytes -= block_group->key.offset; |
8475 | block_group->space_info->bytes_readonly -= block_group->key.offset; | 8518 | block_group->space_info->bytes_readonly -= block_group->key.offset; |
8519 | block_group->space_info->disk_total -= block_group->key.offset * factor; | ||
8476 | spin_unlock(&block_group->space_info->lock); | 8520 | spin_unlock(&block_group->space_info->lock); |
8477 | 8521 | ||
8478 | memcpy(&key, &block_group->key, sizeof(key)); | 8522 | memcpy(&key, &block_group->key, sizeof(key)); |