Skip to content

Commit

Permalink
btrfs: switch to the new mount API
Browse files Browse the repository at this point in the history
Now that we have all of the parts in place to use the new mount API,
switch our fs_type to use the new callbacks.

There are a few things that have to be done at the same time because of
the order of operations changes that come along with the new mount API.
These must be done in the same patch otherwise things will go wrong.

1. Export and use btrfs_check_options in open_ctree().  This is because
   the options are done ahead of time, and we need to check them once we
   have the feature flags loaded.

2. Update the free space cache settings.  Since we're coming in with the
   options already set we need to make sure we don't undo what the user
   has asked for.

3. Set our sb_flags at init_fs_context time, the fs_context stuff is
   trying to manage the sb_flagss itself, so move that into
   init_fs_context and out of the fill super part.

Additionally I've marked the unused functions with __maybe_unused and
will remove them in a future patch.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Acked-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
  • Loading branch information
Josef Bacik authored and David Sterba committed Dec 15, 2023
1 parent f044b31 commit ad21f15
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 41 deletions.
11 changes: 9 additions & 2 deletions fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
88 changes: 49 additions & 39 deletions fs/btrfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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)) {
Expand All @@ -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)
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1929,7 +1942,7 @@ static struct dentry *mount_subvol(const char *subvol_name, u64 subvol_objectid,
* 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;
Expand Down Expand Up @@ -2062,7 +2075,7 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
* 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;
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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;

Expand All @@ -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");

Expand Down Expand Up @@ -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,
};
Expand Down
2 changes: 2 additions & 0 deletions fs/btrfs/super.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit ad21f15

Please sign in to comment.