summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/disk-io.c11
-rw-r--r--fs/btrfs/super.c88
-rw-r--r--fs/btrfs/super.h2
3 files changed, 60 insertions, 41 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 4bac16d74179..beae0dbbc039 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3316,14 +3316,21 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device
*/
btrfs_set_free_space_cache_settings(fs_info);
- ret = btrfs_parse_options(fs_info, options, sb->s_flags);
- if (ret)
+ if (!btrfs_check_options(fs_info, &fs_info->mount_opt, sb->s_flags)) {
+ ret = -EINVAL;
goto fail_alloc;
+ }
ret = btrfs_check_features(fs_info, !sb_rdonly(sb));
if (ret < 0)
goto fail_alloc;
+ /*
+ * At this point our mount options are validated, if we set ->max_inline
+ * to something non-standard make sure we truncate it to sectorsize.
+ */
+ fs_info->max_inline = min_t(u64, fs_info->max_inline, fs_info->sectorsize);
+
if (sectorsize < PAGE_SIZE) {
struct btrfs_subpage_info *subpage_info;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 66c109c85104..4ff26c00eebe 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -307,7 +307,7 @@ static const struct constant_table btrfs_parameter_fragment[] = {
};
#endif
-static const struct fs_parameter_spec btrfs_fs_parameters[] __maybe_unused = {
+static const struct fs_parameter_spec btrfs_fs_parameters[] = {
fsparam_flag_no("acl", Opt_acl),
fsparam_flag_no("autodefrag", Opt_defrag),
fsparam_flag_no("barrier", Opt_barrier),
@@ -738,8 +738,8 @@ static bool check_ro_option(struct btrfs_fs_info *fs_info,
return false;
}
-static bool check_options(struct btrfs_fs_info *info, unsigned long *mount_opt,
- unsigned long flags)
+bool btrfs_check_options(struct btrfs_fs_info *info, unsigned long *mount_opt,
+ unsigned long flags)
{
bool ret = true;
@@ -788,18 +788,6 @@ static bool check_options(struct btrfs_fs_info *info, unsigned long *mount_opt,
*/
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)) {
@@ -809,6 +797,35 @@ void btrfs_set_free_space_cache_settings(struct btrfs_fs_info *fs_info)
btrfs_set_opt(fs_info->mount_opt, FREE_SPACE_TREE);
}
}
+
+ /*
+ * At this point our mount options are populated, so we only mess with
+ * these settings if we don't have any settings already.
+ */
+ if (btrfs_test_opt(fs_info, FREE_SPACE_TREE))
+ return;
+
+ if (btrfs_is_zoned(fs_info) &&
+ btrfs_free_space_cache_v1_active(fs_info)) {
+ btrfs_info(fs_info, "zoned: clearing existing space cache");
+ btrfs_set_super_cache_generation(fs_info->super_copy, 0);
+ return;
+ }
+
+ if (btrfs_test_opt(fs_info, SPACE_CACHE))
+ return;
+
+ if (btrfs_test_opt(fs_info, NOSPACECACHE))
+ return;
+
+ /*
+ * At this point we don't have explicit options set by the user, set
+ * them ourselves based on the state of the file system.
+ */
+ 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))
+ btrfs_set_opt(fs_info->mount_opt, SPACE_CACHE);
}
static int parse_rescue_options(struct btrfs_fs_info *info, const char *options)
@@ -1345,7 +1362,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
}
}
out:
- if (!ret && !check_options(info, &info->mount_opt, new_flags))
+ if (!ret && !btrfs_check_options(info, &info->mount_opt, new_flags))
ret = -EINVAL;
return ret;
}
@@ -1646,10 +1663,6 @@ static int btrfs_fill_super(struct super_block *sb,
#endif
sb->s_xattr = btrfs_xattr_handlers;
sb->s_time_gran = 1;
-#ifdef CONFIG_BTRFS_FS_POSIX_ACL
- sb->s_flags |= SB_POSIXACL;
-#endif
- sb->s_flags |= SB_I_VERSION;
sb->s_iflags |= SB_I_CGROUPWB;
err = super_setup_bdi(sb);
@@ -1929,7 +1942,7 @@ out:
* Note: This is based on mount_bdev from fs/super.c with a few additions
* for multiple device setup. Make sure to keep it in sync.
*/
-static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
+static __maybe_unused struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
int flags, const char *device_name, void *data)
{
struct block_device *bdev = NULL;
@@ -2062,7 +2075,7 @@ error_sec_opts:
* 3. Call mount_subvol() to get the dentry of subvolume. Since there is
* "btrfs subvolume set-default", mount_subvol() is called always.
*/
-static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
+static __maybe_unused struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
const char *device_name, void *data)
{
struct vfsmount *mnt_root;
@@ -2485,7 +2498,7 @@ static int btrfs_reconfigure(struct fs_context *fc)
set_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state);
if (!mount_reconfigure &&
- !check_options(fs_info, &ctx->mount_opt, fc->sb_flags))
+ !btrfs_check_options(fs_info, &ctx->mount_opt, fc->sb_flags))
return -EINVAL;
ret = btrfs_check_features(fs_info, !(fc->sb_flags & SB_RDONLY));
@@ -3147,7 +3160,7 @@ static const struct fs_context_operations btrfs_fs_context_ops = {
.free = btrfs_free_fs_context,
};
-static int __maybe_unused btrfs_init_fs_context(struct fs_context *fc)
+static int btrfs_init_fs_context(struct fs_context *fc)
{
struct btrfs_fs_context *ctx;
@@ -3168,24 +3181,22 @@ static int __maybe_unused btrfs_init_fs_context(struct fs_context *fc)
ctx->commit_interval = BTRFS_DEFAULT_COMMIT_INTERVAL;
}
+#ifdef CONFIG_BTRFS_FS_POSIX_ACL
+ fc->sb_flags |= SB_POSIXACL;
+#endif
+ fc->sb_flags |= SB_I_VERSION;
+
return 0;
}
static struct file_system_type btrfs_fs_type = {
- .owner = THIS_MODULE,
- .name = "btrfs",
- .mount = btrfs_mount,
- .kill_sb = btrfs_kill_super,
- .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA,
-};
-
-static struct file_system_type btrfs_root_fs_type = {
- .owner = THIS_MODULE,
- .name = "btrfs",
- .mount = btrfs_mount_root,
- .kill_sb = btrfs_kill_super,
- .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA | FS_ALLOW_IDMAP,
-};
+ .owner = THIS_MODULE,
+ .name = "btrfs",
+ .init_fs_context = btrfs_init_fs_context,
+ .parameters = btrfs_fs_parameters,
+ .kill_sb = btrfs_kill_super,
+ .fs_flags = FS_REQUIRES_DEV | FS_BINARY_MOUNTDATA | FS_ALLOW_IDMAP,
+ };
MODULE_ALIAS_FS("btrfs");
@@ -3398,7 +3409,6 @@ static const struct super_operations btrfs_super_ops = {
.destroy_inode = btrfs_destroy_inode,
.free_inode = btrfs_free_inode,
.statfs = btrfs_statfs,
- .remount_fs = btrfs_remount,
.freeze_fs = btrfs_freeze,
.unfreeze_fs = btrfs_unfreeze,
};
diff --git a/fs/btrfs/super.h b/fs/btrfs/super.h
index 7c1cd7527e76..7f6577d69902 100644
--- a/fs/btrfs/super.h
+++ b/fs/btrfs/super.h
@@ -3,6 +3,8 @@
#ifndef BTRFS_SUPER_H
#define BTRFS_SUPER_H
+bool btrfs_check_options(struct btrfs_fs_info *info, unsigned long *mount_opt,
+ unsigned long flags);
int btrfs_parse_options(struct btrfs_fs_info *info, char *options,
unsigned long new_flags);
int btrfs_sync_fs(struct super_block *sb, int wait);