aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-10-18 12:15:48 -0400
committerJosef Bacik <josef@redhat.com>2011-10-19 15:12:59 -0400
commit36ba022ac0b748dd543f43430b03198e899426c9 (patch)
tree3175872760ac769cde046b3ac43900fc42856bb8
parent3880a1b46d87a6b030c31889875befc745d95dff (diff)
Btrfs: seperate out btrfs_block_rsv_check out into 2 different functions
Currently btrfs_block_rsv_check does 2 things, it will either refill a block reserve like in the truncate or refill case, or it will check to see if there is enough space in the global reserve and possibly refill it. However because of overcommit we could be well overcommitting ourselves just to try and refill the global reserve, when really we should just be committing the transaction. So breack this out into btrfs_block_rsv_refill and btrfs_block_rsv_check. Refill will try to reserve more metadata if it can and btrfs_block_rsv_check will not, it will only tell you if the factor of the total space is still reserved. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
-rw-r--r--fs/btrfs/ctree.h4
-rw-r--r--fs/btrfs/extent-tree.c41
-rw-r--r--fs/btrfs/free-space-cache.c2
-rw-r--r--fs/btrfs/inode.c4
-rw-r--r--fs/btrfs/relocation.c6
-rw-r--r--fs/btrfs/transaction.c4
6 files changed, 37 insertions, 24 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index ea60897a9171..227620993bce 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2252,8 +2252,10 @@ int btrfs_block_rsv_add(struct btrfs_root *root,
2252 struct btrfs_block_rsv *block_rsv, 2252 struct btrfs_block_rsv *block_rsv,
2253 u64 num_bytes); 2253 u64 num_bytes);
2254int btrfs_block_rsv_check(struct btrfs_root *root, 2254int btrfs_block_rsv_check(struct btrfs_root *root,
2255 struct btrfs_block_rsv *block_rsv, int min_factor);
2256int btrfs_block_rsv_refill(struct btrfs_root *root,
2255 struct btrfs_block_rsv *block_rsv, 2257 struct btrfs_block_rsv *block_rsv,
2256 u64 min_reserved, int min_factor, int flush); 2258 u64 min_reserved);
2257int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv, 2259int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv,
2258 struct btrfs_block_rsv *dst_rsv, 2260 struct btrfs_block_rsv *dst_rsv,
2259 u64 num_bytes); 2261 u64 num_bytes);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index eb4fe56b08bb..a5f1421eeee9 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3422,7 +3422,6 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
3422 * @block_rsv - the block_rsv we're allocating for 3422 * @block_rsv - the block_rsv we're allocating for
3423 * @orig_bytes - the number of bytes we want 3423 * @orig_bytes - the number of bytes we want
3424 * @flush - wether or not we can flush to make our reservation 3424 * @flush - wether or not we can flush to make our reservation
3425 * @check - wether this is just to check if we have enough space or not
3426 * 3425 *
3427 * This will reserve orgi_bytes number of bytes from the space info associated 3426 * This will reserve orgi_bytes number of bytes from the space info associated
3428 * with the block_rsv. If there is not enough space it will make an attempt to 3427 * with the block_rsv. If there is not enough space it will make an attempt to
@@ -3433,7 +3432,7 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
3433 */ 3432 */
3434static int reserve_metadata_bytes(struct btrfs_root *root, 3433static int reserve_metadata_bytes(struct btrfs_root *root,
3435 struct btrfs_block_rsv *block_rsv, 3434 struct btrfs_block_rsv *block_rsv,
3436 u64 orig_bytes, int flush, int check) 3435 u64 orig_bytes, int flush)
3437{ 3436{
3438 struct btrfs_space_info *space_info = block_rsv->space_info; 3437 struct btrfs_space_info *space_info = block_rsv->space_info;
3439 struct btrfs_trans_handle *trans; 3438 struct btrfs_trans_handle *trans;
@@ -3507,7 +3506,7 @@ again:
3507 (orig_bytes * (retries + 1)); 3506 (orig_bytes * (retries + 1));
3508 } 3507 }
3509 3508
3510 if (ret && !check) { 3509 if (ret) {
3511 u64 profile = btrfs_get_alloc_profile(root, 0); 3510 u64 profile = btrfs_get_alloc_profile(root, 0);
3512 u64 avail; 3511 u64 avail;
3513 3512
@@ -3742,7 +3741,7 @@ int btrfs_block_rsv_add(struct btrfs_root *root,
3742 if (num_bytes == 0) 3741 if (num_bytes == 0)
3743 return 0; 3742 return 0;
3744 3743
3745 ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 1, 0); 3744 ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 1);
3746 if (!ret) { 3745 if (!ret) {
3747 block_rsv_add_bytes(block_rsv, num_bytes, 1); 3746 block_rsv_add_bytes(block_rsv, num_bytes, 1);
3748 return 0; 3747 return 0;
@@ -3752,8 +3751,7 @@ int btrfs_block_rsv_add(struct btrfs_root *root,
3752} 3751}
3753 3752
3754int btrfs_block_rsv_check(struct btrfs_root *root, 3753int btrfs_block_rsv_check(struct btrfs_root *root,
3755 struct btrfs_block_rsv *block_rsv, 3754 struct btrfs_block_rsv *block_rsv, int min_factor)
3756 u64 min_reserved, int min_factor, int flush)
3757{ 3755{
3758 u64 num_bytes = 0; 3756 u64 num_bytes = 0;
3759 int ret = -ENOSPC; 3757 int ret = -ENOSPC;
@@ -3762,11 +3760,26 @@ int btrfs_block_rsv_check(struct btrfs_root *root,
3762 return 0; 3760 return 0;
3763 3761
3764 spin_lock(&block_rsv->lock); 3762 spin_lock(&block_rsv->lock);
3765 if (min_factor > 0) 3763 num_bytes = div_factor(block_rsv->size, min_factor);
3766 num_bytes = div_factor(block_rsv->size, min_factor); 3764 if (block_rsv->reserved >= num_bytes)
3767 if (min_reserved > num_bytes) 3765 ret = 0;
3768 num_bytes = min_reserved; 3766 spin_unlock(&block_rsv->lock);
3769 3767
3768 return ret;
3769}
3770
3771int btrfs_block_rsv_refill(struct btrfs_root *root,
3772 struct btrfs_block_rsv *block_rsv,
3773 u64 min_reserved)
3774{
3775 u64 num_bytes = 0;
3776 int ret = -ENOSPC;
3777
3778 if (!block_rsv)
3779 return 0;
3780
3781 spin_lock(&block_rsv->lock);
3782 num_bytes = min_reserved;
3770 if (block_rsv->reserved >= num_bytes) 3783 if (block_rsv->reserved >= num_bytes)
3771 ret = 0; 3784 ret = 0;
3772 else 3785 else
@@ -3776,7 +3789,7 @@ int btrfs_block_rsv_check(struct btrfs_root *root,
3776 if (!ret) 3789 if (!ret)
3777 return 0; 3790 return 0;
3778 3791
3779 ret = reserve_metadata_bytes(root, block_rsv, num_bytes, flush, !flush); 3792 ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 1);
3780 if (!ret) { 3793 if (!ret) {
3781 block_rsv_add_bytes(block_rsv, num_bytes, 0); 3794 block_rsv_add_bytes(block_rsv, num_bytes, 0);
3782 return 0; 3795 return 0;
@@ -4073,7 +4086,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
4073 to_reserve += calc_csum_metadata_size(inode, num_bytes, 1); 4086 to_reserve += calc_csum_metadata_size(inode, num_bytes, 1);
4074 spin_unlock(&BTRFS_I(inode)->lock); 4087 spin_unlock(&BTRFS_I(inode)->lock);
4075 4088
4076 ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush, 0); 4089 ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush);
4077 if (ret) { 4090 if (ret) {
4078 u64 to_free = 0; 4091 u64 to_free = 0;
4079 unsigned dropped; 4092 unsigned dropped;
@@ -5728,7 +5741,7 @@ use_block_rsv(struct btrfs_trans_handle *trans,
5728 block_rsv = get_block_rsv(trans, root); 5741 block_rsv = get_block_rsv(trans, root);
5729 5742
5730 if (block_rsv->size == 0) { 5743 if (block_rsv->size == 0) {
5731 ret = reserve_metadata_bytes(root, block_rsv, blocksize, 0, 0); 5744 ret = reserve_metadata_bytes(root, block_rsv, blocksize, 0);
5732 /* 5745 /*
5733 * If we couldn't reserve metadata bytes try and use some from 5746 * If we couldn't reserve metadata bytes try and use some from
5734 * the global reserve. 5747 * the global reserve.
@@ -5749,7 +5762,7 @@ use_block_rsv(struct btrfs_trans_handle *trans,
5749 return block_rsv; 5762 return block_rsv;
5750 if (ret) { 5763 if (ret) {
5751 WARN_ON(1); 5764 WARN_ON(1);
5752 ret = reserve_metadata_bytes(root, block_rsv, blocksize, 0, 0); 5765 ret = reserve_metadata_bytes(root, block_rsv, blocksize, 0);
5753 if (!ret) { 5766 if (!ret) {
5754 return block_rsv; 5767 return block_rsv;
5755 } else if (ret && block_rsv != global_rsv) { 5768 } else if (ret && block_rsv != global_rsv) {
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 5d40c1ed8225..2fecfc3183ee 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -203,7 +203,7 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
203 203
204 rsv = trans->block_rsv; 204 rsv = trans->block_rsv;
205 trans->block_rsv = root->orphan_block_rsv; 205 trans->block_rsv = root->orphan_block_rsv;
206 ret = btrfs_block_rsv_check(root, root->orphan_block_rsv, 0, 5, 0); 206 ret = btrfs_block_rsv_check(root, root->orphan_block_rsv, 5);
207 if (ret) 207 if (ret)
208 return ret; 208 return ret;
209 209
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index b6b70bdd0992..f12747c9447b 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3604,7 +3604,7 @@ void btrfs_evict_inode(struct inode *inode)
3604 * doing the truncate. 3604 * doing the truncate.
3605 */ 3605 */
3606 while (1) { 3606 while (1) {
3607 ret = btrfs_block_rsv_check(root, rsv, min_size, 0, 1); 3607 ret = btrfs_block_rsv_refill(root, rsv, min_size);
3608 3608
3609 /* 3609 /*
3610 * Try and steal from the global reserve since we will 3610 * Try and steal from the global reserve since we will
@@ -6613,7 +6613,7 @@ static int btrfs_truncate(struct inode *inode)
6613 btrfs_add_ordered_operation(trans, root, inode); 6613 btrfs_add_ordered_operation(trans, root, inode);
6614 6614
6615 while (1) { 6615 while (1) {
6616 ret = btrfs_block_rsv_check(root, rsv, min_size, 0, 1); 6616 ret = btrfs_block_rsv_refill(root, rsv, min_size);
6617 if (ret) { 6617 if (ret) {
6618 /* 6618 /*
6619 * This can only happen with the original transaction we 6619 * This can only happen with the original transaction we
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 7fa090fa0d39..10af6a0e0865 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -2041,8 +2041,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
2041 BUG_ON(IS_ERR(trans)); 2041 BUG_ON(IS_ERR(trans));
2042 trans->block_rsv = rc->block_rsv; 2042 trans->block_rsv = rc->block_rsv;
2043 2043
2044 ret = btrfs_block_rsv_check(root, rc->block_rsv, min_reserved, 2044 ret = btrfs_block_rsv_refill(root, rc->block_rsv, min_reserved);
2045 0, 0);
2046 if (ret) { 2045 if (ret) {
2047 BUG_ON(ret != -EAGAIN); 2046 BUG_ON(ret != -EAGAIN);
2048 ret = btrfs_commit_transaction(trans, root); 2047 ret = btrfs_commit_transaction(trans, root);
@@ -3774,8 +3773,7 @@ restart:
3774 } 3773 }
3775 } 3774 }
3776 3775
3777 ret = btrfs_block_rsv_check(rc->extent_root, rc->block_rsv, 0, 3776 ret = btrfs_block_rsv_check(rc->extent_root, rc->block_rsv, 5);
3778 5, 0);
3779 if (ret < 0) { 3777 if (ret < 0) {
3780 if (ret != -EAGAIN) { 3778 if (ret != -EAGAIN) {
3781 err = ret; 3779 err = ret;
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index d064fa0a4a07..29bef63e23ba 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -418,8 +418,8 @@ static int should_end_transaction(struct btrfs_trans_handle *trans,
418 struct btrfs_root *root) 418 struct btrfs_root *root)
419{ 419{
420 int ret; 420 int ret;
421 ret = btrfs_block_rsv_check(root, &root->fs_info->global_block_rsv, 0, 421
422 5, 0); 422 ret = btrfs_block_rsv_check(root, &root->fs_info->global_block_rsv, 5);
423 return ret ? 1 : 0; 423 return ret ? 1 : 0;
424} 424}
425 425