]> git.dujemihanovic.xyz Git - linux.git/commitdiff
btrfs: enhance unsupported compat RO flags handling
authorQu Wenruo <wqu@suse.com>
Tue, 9 Aug 2022 05:02:16 +0000 (13:02 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 26 Sep 2022 10:28:00 +0000 (12:28 +0200)
Currently there are two corner cases not handling compat RO flags
correctly:

- Remount
  We can still mount the fs RO with compat RO flags, then remount it RW.
  We should not allow any write into a fs with unsupported RO flags.

- Still try to search block group items
  In fact, behavior/on-disk format change to extent tree should not
  need a full incompat flag.

  And since we can ensure fs with unsupported RO flags never got any
  writes (with above case fixed), then we can even skip block group
  items search at mount time.

This patch will enhance the unsupported RO compat flags by:

- Reject read-write remount if there are unsupported RO compat flags

- Go dummy block group items directly for unsupported RO compat flags
  In fact, only changes to chunk/subvolume/root/csum trees should go
  incompat flags.

The latter part should allow future change to extent tree to be compat
RO flags.

Thus this patch also needs to be backported to all stable trees.

CC: stable@vger.kernel.org # 4.9+
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/block-group.c
fs/btrfs/super.c

index 53c44c52cb7964e788e8e6b316bec67ba0cc0688..e7b5a54c82581c45e47f9c63243cd4e337230f80 100644 (file)
@@ -2164,7 +2164,16 @@ int btrfs_read_block_groups(struct btrfs_fs_info *info)
        int need_clear = 0;
        u64 cache_gen;
 
-       if (!root)
+       /*
+        * Either no extent root (with ibadroots rescue option) or we have
+        * unsupported RO options. The fs can never be mounted read-write, so no
+        * need to waste time searching block group items.
+        *
+        * This also allows new extent tree related changes to be RO compat,
+        * no need for a full incompat flag.
+        */
+       if (!root || (btrfs_super_compat_ro_flags(info->super_copy) &
+                     ~BTRFS_FEATURE_COMPAT_RO_SUPP))
                return fill_dummy_bgs(info);
 
        key.objectid = 0;
index 7291e9d67e92f867aa722495fa9befe0fe5c03c5..eb0ae7e396ef42be2da265fafa5d5662840cc25c 100644 (file)
@@ -2117,6 +2117,15 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
                        ret = -EINVAL;
                        goto restore;
                }
+               if (btrfs_super_compat_ro_flags(fs_info->super_copy) &
+                   ~BTRFS_FEATURE_COMPAT_RO_SUPP) {
+                       btrfs_err(fs_info,
+               "can not remount read-write due to unsupported optional flags 0x%llx",
+                               btrfs_super_compat_ro_flags(fs_info->super_copy) &
+                               ~BTRFS_FEATURE_COMPAT_RO_SUPP);
+                       ret = -EINVAL;
+                       goto restore;
+               }
                if (fs_info->fs_devices->rw_devices == 0) {
                        ret = -EACCES;
                        goto restore;