Btrfs: seperate out btrfs_block_rsv_check out into 2 different functions
authorJosef Bacik <josef@redhat.com>
Tue, 18 Oct 2011 16:15:48 +0000 (12:15 -0400)
committerJosef Bacik <josef@redhat.com>
Wed, 19 Oct 2011 19:12:59 +0000 (15:12 -0400)
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>
fs/btrfs/ctree.h
fs/btrfs/extent-tree.c
fs/btrfs/free-space-cache.c
fs/btrfs/inode.c
fs/btrfs/relocation.c
fs/btrfs/transaction.c

index ea60897a9171d520d712e0055972f93d88877cff..227620993bce26e06dc513986a95d4a1cd315f46 100644 (file)
@@ -2252,8 +2252,10 @@ int btrfs_block_rsv_add(struct btrfs_root *root,
                        struct btrfs_block_rsv *block_rsv,
                        u64 num_bytes);
 int btrfs_block_rsv_check(struct btrfs_root *root,
+                         struct btrfs_block_rsv *block_rsv, int min_factor);
+int btrfs_block_rsv_refill(struct btrfs_root *root,
                          struct btrfs_block_rsv *block_rsv,
-                         u64 min_reserved, int min_factor, int flush);
+                         u64 min_reserved);
 int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv,
                            struct btrfs_block_rsv *dst_rsv,
                            u64 num_bytes);
index eb4fe56b08bbc51bb2880d25863c8a9bf31e9a89..a5f1421eeee91b84c14af7abf290cbd227a3a21a 100644 (file)
@@ -3422,7 +3422,6 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
  * @block_rsv - the block_rsv we're allocating for
  * @orig_bytes - the number of bytes we want
  * @flush - wether or not we can flush to make our reservation
- * @check - wether this is just to check if we have enough space or not
  *
  * This will reserve orgi_bytes number of bytes from the space info associated
  * 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,
  */
 static int reserve_metadata_bytes(struct btrfs_root *root,
                                  struct btrfs_block_rsv *block_rsv,
-                                 u64 orig_bytes, int flush, int check)
+                                 u64 orig_bytes, int flush)
 {
        struct btrfs_space_info *space_info = block_rsv->space_info;
        struct btrfs_trans_handle *trans;
@@ -3507,7 +3506,7 @@ again:
                        (orig_bytes * (retries + 1));
        }
 
-       if (ret && !check) {
+       if (ret) {
                u64 profile = btrfs_get_alloc_profile(root, 0);
                u64 avail;
 
@@ -3742,7 +3741,7 @@ int btrfs_block_rsv_add(struct btrfs_root *root,
        if (num_bytes == 0)
                return 0;
 
-       ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 1, 0);
+       ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 1);
        if (!ret) {
                block_rsv_add_bytes(block_rsv, num_bytes, 1);
                return 0;
@@ -3752,8 +3751,7 @@ int btrfs_block_rsv_add(struct btrfs_root *root,
 }
 
 int btrfs_block_rsv_check(struct btrfs_root *root,
-                         struct btrfs_block_rsv *block_rsv,
-                         u64 min_reserved, int min_factor, int flush)
+                         struct btrfs_block_rsv *block_rsv, int min_factor)
 {
        u64 num_bytes = 0;
        int ret = -ENOSPC;
@@ -3762,11 +3760,26 @@ int btrfs_block_rsv_check(struct btrfs_root *root,
                return 0;
 
        spin_lock(&block_rsv->lock);
-       if (min_factor > 0)
-               num_bytes = div_factor(block_rsv->size, min_factor);
-       if (min_reserved > num_bytes)
-               num_bytes = min_reserved;
+       num_bytes = div_factor(block_rsv->size, min_factor);
+       if (block_rsv->reserved >= num_bytes)
+               ret = 0;
+       spin_unlock(&block_rsv->lock);
 
+       return ret;
+}
+
+int btrfs_block_rsv_refill(struct btrfs_root *root,
+                         struct btrfs_block_rsv *block_rsv,
+                         u64 min_reserved)
+{
+       u64 num_bytes = 0;
+       int ret = -ENOSPC;
+
+       if (!block_rsv)
+               return 0;
+
+       spin_lock(&block_rsv->lock);
+       num_bytes = min_reserved;
        if (block_rsv->reserved >= num_bytes)
                ret = 0;
        else
@@ -3776,7 +3789,7 @@ int btrfs_block_rsv_check(struct btrfs_root *root,
        if (!ret)
                return 0;
 
-       ret = reserve_metadata_bytes(root, block_rsv, num_bytes, flush, !flush);
+       ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 1);
        if (!ret) {
                block_rsv_add_bytes(block_rsv, num_bytes, 0);
                return 0;
@@ -4073,7 +4086,7 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
        to_reserve += calc_csum_metadata_size(inode, num_bytes, 1);
        spin_unlock(&BTRFS_I(inode)->lock);
 
-       ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush, 0);
+       ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush);
        if (ret) {
                u64 to_free = 0;
                unsigned dropped;
@@ -5728,7 +5741,7 @@ use_block_rsv(struct btrfs_trans_handle *trans,
        block_rsv = get_block_rsv(trans, root);
 
        if (block_rsv->size == 0) {
-               ret = reserve_metadata_bytes(root, block_rsv, blocksize, 0, 0);
+               ret = reserve_metadata_bytes(root, block_rsv, blocksize, 0);
                /*
                 * If we couldn't reserve metadata bytes try and use some from
                 * the global reserve.
@@ -5749,7 +5762,7 @@ use_block_rsv(struct btrfs_trans_handle *trans,
                return block_rsv;
        if (ret) {
                WARN_ON(1);
-               ret = reserve_metadata_bytes(root, block_rsv, blocksize, 0, 0);
+               ret = reserve_metadata_bytes(root, block_rsv, blocksize, 0);
                if (!ret) {
                        return block_rsv;
                } else if (ret && block_rsv != global_rsv) {
index 5d40c1ed822550985fb2cee80cc1400b239f16e0..2fecfc3183ee339afc631dfbf5c0326bb4c88e87 100644 (file)
@@ -203,7 +203,7 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
 
        rsv = trans->block_rsv;
        trans->block_rsv = root->orphan_block_rsv;
-       ret = btrfs_block_rsv_check(root, root->orphan_block_rsv, 0, 5, 0);
+       ret = btrfs_block_rsv_check(root, root->orphan_block_rsv, 5);
        if (ret)
                return ret;
 
index b6b70bdd0992ee61cc59b29ae861b9d65f4fc362..f12747c9447bb4b6e2122cdf7375a84d06b894ce 100644 (file)
@@ -3604,7 +3604,7 @@ void btrfs_evict_inode(struct inode *inode)
         * doing the truncate.
         */
        while (1) {
-               ret = btrfs_block_rsv_check(root, rsv, min_size, 0, 1);
+               ret = btrfs_block_rsv_refill(root, rsv, min_size);
 
                /*
                 * Try and steal from the global reserve since we will
@@ -6613,7 +6613,7 @@ static int btrfs_truncate(struct inode *inode)
                btrfs_add_ordered_operation(trans, root, inode);
 
        while (1) {
-               ret = btrfs_block_rsv_check(root, rsv, min_size, 0, 1);
+               ret = btrfs_block_rsv_refill(root, rsv, min_size);
                if (ret) {
                        /*
                         * This can only happen with the original transaction we
index 7fa090fa0d39e100efa35a443fe174eefd45f63a..10af6a0e08651c281ed0484dd5aacff9b17738d5 100644 (file)
@@ -2041,8 +2041,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
                BUG_ON(IS_ERR(trans));
                trans->block_rsv = rc->block_rsv;
 
-               ret = btrfs_block_rsv_check(root, rc->block_rsv, min_reserved,
-                                           0, 0);
+               ret = btrfs_block_rsv_refill(root, rc->block_rsv, min_reserved);
                if (ret) {
                        BUG_ON(ret != -EAGAIN);
                        ret = btrfs_commit_transaction(trans, root);
@@ -3774,8 +3773,7 @@ restart:
                        }
                }
 
-               ret = btrfs_block_rsv_check(rc->extent_root, rc->block_rsv, 0,
-                                           5, 0);
+               ret = btrfs_block_rsv_check(rc->extent_root, rc->block_rsv, 5);
                if (ret < 0) {
                        if (ret != -EAGAIN) {
                                err = ret;
index d064fa0a4a078e306c9987d4319f2878ffbbda2c..29bef63e23ba4b235b9726df2524422788992525 100644 (file)
@@ -418,8 +418,8 @@ static int should_end_transaction(struct btrfs_trans_handle *trans,
                                  struct btrfs_root *root)
 {
        int ret;
-       ret = btrfs_block_rsv_check(root, &root->fs_info->global_block_rsv, 0,
-                                   5, 0);
+
+       ret = btrfs_block_rsv_check(root, &root->fs_info->global_block_rsv, 5);
        return ret ? 1 : 0;
 }