*/
int btrfs_stripe_alloc_check_support(struct btrfs_fs_info *fs_info)
{
- if (!btrfs_test_opt(fs_info, FREE_SPACE_TREE)) {
+ /*
+ * Mirror btrfs_check_mountopts(): only the v1 space cache is a
+ * problem. Its cache inode is nodatacow and preallocated, so a
+ * commit overwrites it in place -- a sub-stripe write into committed
+ * stripes that no csum would show afterwards. The free space tree
+ * and no cache at all are both fine; nothing here reads either one.
+ * The property can arrive on a live filesystem, after
+ * btrfs_read_block_groups() checked for cache inodes left on disk by
+ * an earlier mount, so ask again here.
+ */
+ if (btrfs_test_opt(fs_info, SPACE_CACHE)) {
btrfs_err(fs_info,
- "stripe_alloc requires the free space tree (space_cache=v2)");
+ "stripe_alloc is not supported with space_cache=v1");
+ return -EINVAL;
+ }
+ if (btrfs_free_space_cache_v1_present(fs_info)) {
+ btrfs_err(fs_info,
+"stripe_alloc is not supported while a v1 space cache is present on disk; mount once without stripe_alloc to clear it (-o clear_cache, or space_cache=v2)");
return -EINVAL;
}
if (btrfs_is_zoned(fs_info)) {