|
@@ -597,6 +597,29 @@ static int btrfs_delayed_inode_reserve_metadata(
|
|
|
|
|
|
num_bytes = btrfs_calc_trans_metadata_size(root, 1);
|
|
|
|
|
|
+ /*
|
|
|
+ * If our block_rsv is the delalloc block reserve then check and see if
|
|
|
+ * we have our extra reservation for updating the inode. If not fall
|
|
|
+ * through and try to reserve space quickly.
|
|
|
+ *
|
|
|
+ * We used to try and steal from the delalloc block rsv or the global
|
|
|
+ * reserve, but we'd steal a full reservation, which isn't kind. We are
|
|
|
+ * here through delalloc which means we've likely just cowed down close
|
|
|
+ * to the leaf that contains the inode, so we would steal less just
|
|
|
+ * doing the fallback inode update, so if we do end up having to steal
|
|
|
+ * from the global block rsv we hopefully only steal one or two blocks
|
|
|
+ * worth which is less likely to hurt us.
|
|
|
+ */
|
|
|
+ if (src_rsv && src_rsv->type == BTRFS_BLOCK_RSV_DELALLOC) {
|
|
|
+ spin_lock(&BTRFS_I(inode)->lock);
|
|
|
+ if (test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED,
|
|
|
+ &BTRFS_I(inode)->runtime_flags))
|
|
|
+ release = true;
|
|
|
+ else
|
|
|
+ src_rsv = NULL;
|
|
|
+ spin_unlock(&BTRFS_I(inode)->lock);
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* btrfs_dirty_inode will update the inode under btrfs_join_transaction
|
|
|
* which doesn't reserve space for speed. This is a problem since we
|
|
@@ -626,51 +649,10 @@ static int btrfs_delayed_inode_reserve_metadata(
|
|
|
num_bytes, 1);
|
|
|
}
|
|
|
return ret;
|
|
|
- } else if (src_rsv->type == BTRFS_BLOCK_RSV_DELALLOC) {
|
|
|
- spin_lock(&BTRFS_I(inode)->lock);
|
|
|
- if (test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED,
|
|
|
- &BTRFS_I(inode)->runtime_flags)) {
|
|
|
- spin_unlock(&BTRFS_I(inode)->lock);
|
|
|
- release = true;
|
|
|
- goto migrate;
|
|
|
- }
|
|
|
- spin_unlock(&BTRFS_I(inode)->lock);
|
|
|
-
|
|
|
- /* Ok we didn't have space pre-reserved. This shouldn't happen
|
|
|
- * too often but it can happen if we do delalloc to an existing
|
|
|
- * inode which gets dirtied because of the time update, and then
|
|
|
- * isn't touched again until after the transaction commits and
|
|
|
- * then we try to write out the data. First try to be nice and
|
|
|
- * reserve something strictly for us. If not be a pain and try
|
|
|
- * to steal from the delalloc block rsv.
|
|
|
- */
|
|
|
- ret = btrfs_block_rsv_add(root, dst_rsv, num_bytes,
|
|
|
- BTRFS_RESERVE_NO_FLUSH);
|
|
|
- if (!ret)
|
|
|
- goto out;
|
|
|
-
|
|
|
- ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1);
|
|
|
- if (!ret)
|
|
|
- goto out;
|
|
|
-
|
|
|
- if (btrfs_test_opt(root, ENOSPC_DEBUG)) {
|
|
|
- btrfs_debug(root->fs_info,
|
|
|
- "block rsv migrate returned %d", ret);
|
|
|
- WARN_ON(1);
|
|
|
- }
|
|
|
- /*
|
|
|
- * Ok this is a problem, let's just steal from the global rsv
|
|
|
- * since this really shouldn't happen that often.
|
|
|
- */
|
|
|
- ret = btrfs_block_rsv_migrate(&root->fs_info->global_block_rsv,
|
|
|
- dst_rsv, num_bytes, 1);
|
|
|
- goto out;
|
|
|
}
|
|
|
|
|
|
-migrate:
|
|
|
ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1);
|
|
|
|
|
|
-out:
|
|
|
/*
|
|
|
* Migrate only takes a reservation, it doesn't touch the size of the
|
|
|
* block_rsv. This is to simplify people who don't normally have things
|