diff options
-rw-r--r-- | fs/btrfs/disk-io.c | 17 | ||||
-rw-r--r-- | fs/btrfs/super.c | 56 | ||||
-rw-r--r-- | fs/btrfs/super.h | 1 |
3 files changed, 50 insertions, 24 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 969887b2f8fe..33e48e3865c5 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -3305,6 +3305,12 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device fs_info->csums_per_leaf = BTRFS_MAX_ITEM_SIZE(fs_info) / fs_info->csum_size; fs_info->stripesize = stripesize; + /* + * Handle the space caching options appropriately now that we have the + * super block loaded and validated. + */ + btrfs_set_free_space_cache_settings(fs_info); + ret = btrfs_parse_options(fs_info, options, sb->s_flags); if (ret) goto fail_alloc; @@ -3316,17 +3322,6 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device if (sectorsize < PAGE_SIZE) { struct btrfs_subpage_info *subpage_info; - /* - * V1 space cache has some hardcoded PAGE_SIZE usage, and is - * going to be deprecated. - * - * Force to use v2 cache for subpage case. - */ - btrfs_clear_opt(fs_info->mount_opt, SPACE_CACHE); - btrfs_set_and_info(fs_info, FREE_SPACE_TREE, - "forcing free space tree for sector size %u with page size %lu", - sectorsize, PAGE_SIZE); - btrfs_warn(fs_info, "read-write for sector size %u with page size %lu is experimental", sectorsize, PAGE_SIZE); diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 2be3ae63b153..332d6d2c9376 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -271,6 +271,43 @@ static bool check_options(struct btrfs_fs_info *info, unsigned long flags) return ret; } +/* + * This is subtle, we only call this during open_ctree(). We need to pre-load + * the mount options with the on-disk settings. Before the new mount API took + * effect we would do this on mount and remount. With the new mount API we'll + * only do this on the initial mount. + * + * This isn't a change in behavior, because we're using the current state of the + * file system to set the current mount options. If you mounted with special + * options to disable these features and then remounted we wouldn't revert the + * settings, because mounting without these features cleared the on-disk + * settings, so this being called on re-mount is not needed. + */ +void btrfs_set_free_space_cache_settings(struct btrfs_fs_info *fs_info) +{ + if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) + btrfs_set_opt(fs_info->mount_opt, FREE_SPACE_TREE); + else if (btrfs_free_space_cache_v1_active(fs_info)) { + if (btrfs_is_zoned(fs_info)) { + btrfs_info(fs_info, + "zoned: clearing existing space cache"); + btrfs_set_super_cache_generation(fs_info->super_copy, 0); + } else { + btrfs_set_opt(fs_info->mount_opt, SPACE_CACHE); + } + } + + if (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); + } + } +} + static int parse_rescue_options(struct btrfs_fs_info *info, const char *options) { char *opts; @@ -350,18 +387,6 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, bool saved_compress_force; int no_compress = 0; - if (btrfs_fs_compat_ro(info, FREE_SPACE_TREE)) - btrfs_set_opt(info->mount_opt, FREE_SPACE_TREE); - else if (btrfs_free_space_cache_v1_active(info)) { - if (btrfs_is_zoned(info)) { - btrfs_info(info, - "zoned: clearing existing space cache"); - btrfs_set_super_cache_generation(info->super_copy, 0); - } else { - btrfs_set_opt(info->mount_opt, SPACE_CACHE); - } - } - /* * Even the options are empty, we still need to do extra check * against new flags @@ -654,8 +679,13 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, * compat_ro(FREE_SPACE_TREE) set, and we aren't going * to allow v1 to be set for extent tree v2, simply * ignore this setting if we're extent tree v2. + * + * For subpage blocksize we don't allow space cache v1, + * and we'll turn on v2, so we can skip the settings + * here as well. */ - if (btrfs_fs_incompat(info, EXTENT_TREE_V2)) + if (btrfs_fs_incompat(info, EXTENT_TREE_V2) || + info->sectorsize < PAGE_SIZE) break; if (token == Opt_space_cache || strcmp(args[0].from, "v1") == 0) { diff --git a/fs/btrfs/super.h b/fs/btrfs/super.h index 8dbb909b364f..7c1cd7527e76 100644 --- a/fs/btrfs/super.h +++ b/fs/btrfs/super.h @@ -8,6 +8,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, int btrfs_sync_fs(struct super_block *sb, int wait); char *btrfs_get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info, u64 subvol_objectid); +void btrfs_set_free_space_cache_settings(struct btrfs_fs_info *fs_info); static inline struct btrfs_fs_info *btrfs_sb(struct super_block *sb) { |