|
@@ -6656,48 +6656,39 @@ 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,
|
|
|
- BTRFS_RESERVE_NO_FLUSH);
|
|
|
- /*
|
|
|
- * If we couldn't reserve metadata bytes try and use some from
|
|
|
- * the global reserve.
|
|
|
- */
|
|
|
- if (ret && block_rsv != global_rsv) {
|
|
|
- ret = block_rsv_use_bytes(global_rsv, blocksize);
|
|
|
- if (!ret)
|
|
|
- return global_rsv;
|
|
|
- return ERR_PTR(ret);
|
|
|
- } else if (ret) {
|
|
|
- return ERR_PTR(ret);
|
|
|
- }
|
|
|
- return block_rsv;
|
|
|
- }
|
|
|
+ if (unlikely(block_rsv->size == 0))
|
|
|
+ goto try_reserve;
|
|
|
|
|
|
ret = block_rsv_use_bytes(block_rsv, blocksize);
|
|
|
if (!ret)
|
|
|
return block_rsv;
|
|
|
- if (ret && !block_rsv->failfast) {
|
|
|
- if (btrfs_test_opt(root, ENOSPC_DEBUG)) {
|
|
|
- static DEFINE_RATELIMIT_STATE(_rs,
|
|
|
- DEFAULT_RATELIMIT_INTERVAL * 10,
|
|
|
- /*DEFAULT_RATELIMIT_BURST*/ 1);
|
|
|
- if (__ratelimit(&_rs))
|
|
|
- WARN(1, KERN_DEBUG
|
|
|
- "btrfs: block rsv returned %d\n", ret);
|
|
|
- }
|
|
|
- ret = reserve_metadata_bytes(root, block_rsv, blocksize,
|
|
|
- BTRFS_RESERVE_NO_FLUSH);
|
|
|
- if (!ret) {
|
|
|
- return block_rsv;
|
|
|
- } else if (ret && block_rsv != global_rsv) {
|
|
|
- ret = block_rsv_use_bytes(global_rsv, blocksize);
|
|
|
- if (!ret)
|
|
|
- return global_rsv;
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
- return ERR_PTR(-ENOSPC);
|
|
|
+ if (block_rsv->failfast)
|
|
|
+ return ERR_PTR(ret);
|
|
|
+
|
|
|
+ if (btrfs_test_opt(root, ENOSPC_DEBUG)) {
|
|
|
+ static DEFINE_RATELIMIT_STATE(_rs,
|
|
|
+ DEFAULT_RATELIMIT_INTERVAL * 10,
|
|
|
+ /*DEFAULT_RATELIMIT_BURST*/ 1);
|
|
|
+ if (__ratelimit(&_rs))
|
|
|
+ WARN(1, KERN_DEBUG
|
|
|
+ "btrfs: block rsv returned %d\n", ret);
|
|
|
+ }
|
|
|
+try_reserve:
|
|
|
+ ret = reserve_metadata_bytes(root, block_rsv, blocksize,
|
|
|
+ BTRFS_RESERVE_NO_FLUSH);
|
|
|
+ if (!ret)
|
|
|
+ return block_rsv;
|
|
|
+ /*
|
|
|
+ * If we couldn't reserve metadata bytes try and use some from
|
|
|
+ * the global reserve.
|
|
|
+ */
|
|
|
+ if (block_rsv->type != BTRFS_BLOCK_RSV_GLOBAL) {
|
|
|
+ ret = block_rsv_use_bytes(global_rsv, blocksize);
|
|
|
+ if (!ret)
|
|
|
+ return global_rsv;
|
|
|
+ }
|
|
|
+ return ERR_PTR(ret);
|
|
|
}
|
|
|
|
|
|
static void unuse_block_rsv(struct btrfs_fs_info *fs_info,
|