btrfs: properly reject clear_cache and v1 cache for block-group-tree
authorQu Wenruo <wqu@suse.com>
Thu, 27 Apr 2023 01:45:32 +0000 (09:45 +0800)
committerDavid Sterba <dsterba@suse.com>
Fri, 28 Apr 2023 14:36:45 +0000 (16:36 +0200)
[BUG]
With block-group-tree feature enabled, mounting it with clear_cache
would cause the following transaction abort at mount or remount:

  BTRFS info (device dm-4): force clearing of disk cache
  BTRFS info (device dm-4): using free space tree
  BTRFS info (device dm-4): auto enabling async discard
  BTRFS info (device dm-4): clearing free space tree
  BTRFS info (device dm-4): clearing compat-ro feature flag for FREE_SPACE_TREE (0x1)
  BTRFS info (device dm-4): clearing compat-ro feature flag for FREE_SPACE_TREE_VALID (0x2)
  BTRFS error (device dm-4): block-group-tree feature requires fres-space-tree and no-holes
  BTRFS error (device dm-4): super block corruption detected before writing it to disk
  BTRFS: error (device dm-4) in write_all_supers:4288: errno=-117 Filesystem corrupted (unexpected superblock corruption detected)
  BTRFS warning (device dm-4: state E): Skipping commit of aborted transaction.

[CAUSE]
For block-group-tree feature, we have an artificial dependency on
free-space-tree.

This means if we detect block-group-tree without v2 cache, we consider
it a corruption and cause the problem.

For clear_cache mount option, it would temporary disable v2 cache, then
re-enable it.

But unfortunately for that temporary v2 cache disabled status, we refuse
to write a superblock with bg tree only flag, thus leads to the above
transaction abortion.

[FIX]
For now, just reject clear_cache and v1 cache mount option for block
group tree.  So now we got a graceful rejection other than a transaction
abort:

  BTRFS info (device dm-4): force clearing of disk cache
  BTRFS error (device dm-4): cannot disable free space tree with block-group-tree feature
  BTRFS error (device dm-4): open_ctree failed

CC: stable@vger.kernel.org # 6.1+
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/super.c

index 6cb97ef..0f2f915 100644 (file)
@@ -826,7 +826,12 @@ out:
            !btrfs_test_opt(info, CLEAR_CACHE)) {
                btrfs_err(info, "cannot disable free space tree");
                ret = -EINVAL;
-
+       }
+       if (btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE) &&
+           (btrfs_test_opt(info, CLEAR_CACHE) ||
+            !btrfs_test_opt(info, FREE_SPACE_TREE))) {
+               btrfs_err(info, "cannot disable free space tree with block-group-tree feature");
+               ret = -EINVAL;
        }
        if (!ret)
                ret = btrfs_check_mountopts_zoned(info);