aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/extent-tree.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 7af618dcf2c..ff6bbfd75cf 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -5646,6 +5646,7 @@ use_block_rsv(struct btrfs_trans_handle *trans,
5646 struct btrfs_root *root, u32 blocksize) 5646 struct btrfs_root *root, u32 blocksize)
5647{ 5647{
5648 struct btrfs_block_rsv *block_rsv; 5648 struct btrfs_block_rsv *block_rsv;
5649 struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv;
5649 int ret; 5650 int ret;
5650 5651
5651 block_rsv = get_block_rsv(trans, root); 5652 block_rsv = get_block_rsv(trans, root);
@@ -5653,14 +5654,39 @@ use_block_rsv(struct btrfs_trans_handle *trans,
5653 if (block_rsv->size == 0) { 5654 if (block_rsv->size == 0) {
5654 ret = reserve_metadata_bytes(trans, root, block_rsv, 5655 ret = reserve_metadata_bytes(trans, root, block_rsv,
5655 blocksize, 0); 5656 blocksize, 0);
5656 if (ret) 5657 /*
5658 * If we couldn't reserve metadata bytes try and use some from
5659 * the global reserve.
5660 */
5661 if (ret && block_rsv != global_rsv) {
5662 ret = block_rsv_use_bytes(global_rsv, blocksize);
5663 if (!ret)
5664 return global_rsv;
5665 return ERR_PTR(ret);
5666 } else if (ret) {
5657 return ERR_PTR(ret); 5667 return ERR_PTR(ret);
5668 }
5658 return block_rsv; 5669 return block_rsv;
5659 } 5670 }
5660 5671
5661 ret = block_rsv_use_bytes(block_rsv, blocksize); 5672 ret = block_rsv_use_bytes(block_rsv, blocksize);
5662 if (!ret) 5673 if (!ret)
5663 return block_rsv; 5674 return block_rsv;
5675 if (ret) {
5676 WARN_ON(1);
5677 ret = reserve_metadata_bytes(trans, root, block_rsv, blocksize,
5678 0);
5679 if (!ret) {
5680 spin_lock(&block_rsv->lock);
5681 block_rsv->size += blocksize;
5682 spin_unlock(&block_rsv->lock);
5683 return block_rsv;
5684 } else if (ret && block_rsv != global_rsv) {
5685 ret = block_rsv_use_bytes(global_rsv, blocksize);
5686 if (!ret)
5687 return global_rsv;
5688 }
5689 }
5664 5690
5665 return ERR_PTR(-ENOSPC); 5691 return ERR_PTR(-ENOSPC);
5666} 5692}