]> git.baikalelectronics.ru Git - kernel.git/commitdiff
btrfs: subpage: reject raid56 filesystem and profile conversion
authorQu Wenruo <wqu@suse.com>
Mon, 26 Jul 2021 06:35:01 +0000 (14:35 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 23 Aug 2021 11:19:05 +0000 (13:19 +0200)
RAID56 is not only unsafe due to its write-hole problem, but also has
tons of hardcoded PAGE_SIZE.

Disable it for subpage support for now.

Reviewed-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/disk-io.c
fs/btrfs/volumes.c

index a59ab7b9aea08762b165cd9adfe894e870a593be..b9ba244de1d11306ed132c56a5f6b24bf230a15f 100644 (file)
@@ -3402,6 +3402,16 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
                        goto fail_alloc;
                }
        }
+       if (sectorsize != PAGE_SIZE) {
+               if (btrfs_super_incompat_flags(fs_info->super_copy) &
+                       BTRFS_FEATURE_INCOMPAT_RAID56) {
+                       btrfs_err(fs_info,
+               "RAID56 is not yet supported for sector size %u with page size %lu",
+                               sectorsize, PAGE_SIZE);
+                       err = -EINVAL;
+                       goto fail_alloc;
+               }
+       }
 
        ret = btrfs_init_workqueues(fs_info, fs_devices);
        if (ret) {
index d42fb61aadc359beebc4d8ca81b997655bdd09f3..8e61307ffad20eead465aa231493b7a407a314ae 100644 (file)
@@ -3968,6 +3968,13 @@ static inline int validate_convert_profile(struct btrfs_fs_info *fs_info,
        if (!(bargs->flags & BTRFS_BALANCE_ARGS_CONVERT))
                return true;
 
+       if (fs_info->sectorsize < PAGE_SIZE &&
+               bargs->target & BTRFS_BLOCK_GROUP_RAID56_MASK) {
+               btrfs_err(fs_info,
+               "RAID56 is not yet supported for sectorsize %u with page size %lu",
+                         fs_info->sectorsize, PAGE_SIZE);
+               return false;
+       }
        /* Profile is valid and does not have bits outside of the allowed set */
        if (alloc_profile_is_valid(bargs->target, 1) &&
            (bargs->target & ~allowed) == 0)