]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: only enforce free space tree if v1 cache is required for bs < ps cases
authorQu Wenruo <wqu@suse.com>
Thu, 18 Dec 2025 04:45:28 +0000 (15:15 +1030)
committerDavid Sterba <dsterba@suse.com>
Tue, 6 Jan 2026 00:22:59 +0000 (01:22 +0100)
[BUG]
Since the introduction of btrfs bs < ps support, v1 cache was never on
the plan due to its hard coded PAGE_SIZE usage, and the future plan to
properly deprecate it.

However for bs < ps cases, even if 'nospace_cache,clear_cache' mount
option is specified, it's never respected and free space tree is always
enabled:

  mkfs.btrfs -f -O ^bgt,fst $dev
  mount $dev $mnt -o clear_cache,nospace_cache
  umount $mnt
  btrfs ins dump-super $dev
  ...
  compat_ro_flags 0x3
          ( FREE_SPACE_TREE |
            FREE_SPACE_TREE_VALID )
  ...

This means a different behavior compared to bs >= ps cases.

[CAUSE]
The forcing usage of v2 space cache is done inside
btrfs_set_free_space_cache_settings(), however it never checks if we're
even using space cache but always enabling v2 cache.

[FIX]
Instead unconditionally enable v2 cache, only forcing v2 cache if the
old v1 cache is required.

Now v2 space cache can be properly disabled on bs < ps cases:

  mkfs.btrfs -f -O ^bgt,fst $dev
  mount $dev $mnt -o clear_cache,nospace_cache
  umount $mnt
  btrfs ins dump-super $dev
  ...
  compat_ro_flags 0x0
  ...

Fixes: 9f73f1aef98b ("btrfs: force v2 space cache usage for subpage mount")
Reviewed-by: Filipe Manana <fdmanana@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/super.c

index 1999533b52bee99ca07ef4ae730547a6298f6437..9f8546498818324c00cbaa4ba326fc53c12ecd33 100644 (file)
@@ -736,14 +736,12 @@ bool btrfs_check_options(const struct btrfs_fs_info *info,
  */
 void btrfs_set_free_space_cache_settings(struct btrfs_fs_info *fs_info)
 {
-       if (fs_info->sectorsize < PAGE_SIZE) {
+       if (fs_info->sectorsize < PAGE_SIZE && btrfs_test_opt(fs_info, SPACE_CACHE)) {
+               btrfs_info(fs_info,
+                          "forcing free space tree for sector size %u with page size %lu",
+                          fs_info->sectorsize, PAGE_SIZE);
                btrfs_clear_opt(fs_info->mount_opt, SPACE_CACHE);
-               if (!btrfs_test_opt(fs_info, FREE_SPACE_TREE)) {
-                       btrfs_info(fs_info,
-                                  "forcing free space tree for sector size %u with page size %lu",
-                                  fs_info->sectorsize, PAGE_SIZE);
-                       btrfs_set_opt(fs_info->mount_opt, FREE_SPACE_TREE);
-               }
+               btrfs_set_opt(fs_info->mount_opt, FREE_SPACE_TREE);
        }
 
        /*