From: Chao Yu <chao@kernel.org>
To: Hongbo Li <lihongbo22@huawei.com>, Eric Sandeen <sandeen@redhat.com>
Cc: chao@kernel.org, linux-fsdevel@vger.kernel.org,
jaegeuk@kernel.org, linux-f2fs-devel@lists.sourceforge.net
Subject: Re: [PATCH V3 7/7] f2fs: switch to the new mount api
Date: Wed, 14 May 2025 12:03:39 +0800 [thread overview]
Message-ID: <979015aa-433d-4057-a454-afaea2c68131@kernel.org> (raw)
In-Reply-To: <63d1977d-2f0b-4c58-9867-0dc1285815a0@huawei.com>
On 5/14/25 10:33, Hongbo Li wrote:
>
>
> On 2025/5/13 16:59, Chao Yu wrote:
>> On 4/24/25 01:08, Eric Sandeen wrote:
>>> From: Hongbo Li <lihongbo22@huawei.com>
>>>
>>> The new mount api will execute .parse_param, .init_fs_context, .get_tree
>>> and will call .remount if remount happened. So we add the necessary
>>> functions for the fs_context_operations. If .init_fs_context is added,
>>> the old .mount should remove.
>>>
>>> See Documentation/filesystems/mount_api.rst for more information.
>>
>> mkfs.f2fs -f -O extra_attr,flexible_inline_xattr /dev/vdb
>> mount -o inline_xattr_size=512 /dev/vdb /mnt/f2fs
>> mount: /mnt/f2fs: wrong fs type, bad option, bad superblock on /dev/vdb, missing codepage or helper program, or other error.
>> dmesg(1) may have more information after failed mount system call.
>> dmesg
>> [ 1758.202282] F2FS-fs (vdb): Image doesn't support compression
>> [ 1758.202286] F2FS-fs (vdb): inline_xattr_size option should be set with inline_xattr option
>>
>> Eric, Hongbo, can you please take a look at this issue?
>>
> Sorry, we only check the option hold in ctx, we should do the double check in sbi. Or other elegant approaches.
>
> For the "support compression", is it also the error in this testcase?
I think so, I checked this w/ additional logs, and found this:
#define F2FS_MOUNT_INLINE_XATTR_SIZE 0x00080000
#define F2FS_SPEC_compress_chksum (1 << 19) /* equal to 0x00080000)
if (!f2fs_sb_has_compression(sbi)) {
if (test_compression_spec(ctx->opt_mask) ||
ctx_test_opt(ctx, F2FS_MOUNT_COMPRESS_CACHE))
f2fs_info(sbi, "Image doesn't support compression");
clear_compression_spec(ctx);
ctx->opt_mask &= ~F2FS_MOUNT_COMPRESS_CACHE;
return 0;
}
We should use test_compression_spec(ctx->spec_mask) instead of
test_compression_spec(ctx->opt_mask) to check special mask of compression
option?
Thanks,
>
> Thanks,
> Hongbo
>
>> Thanks,
>>
>>>
>>> Signed-off-by: Hongbo Li <lihongbo22@huawei.com>
>>> [sandeen: forward port]
>>> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
>>> ---
>>> fs/f2fs/super.c | 156 +++++++++++++++++++-----------------------------
>>> 1 file changed, 62 insertions(+), 94 deletions(-)
>>>
>>> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
>>> index 37497fd80bb9..041bd6c482a0 100644
>>> --- a/fs/f2fs/super.c
>>> +++ b/fs/f2fs/super.c
>>> @@ -1141,47 +1141,6 @@ static int f2fs_parse_param(struct fs_context *fc, struct fs_parameter *param)
>>> return 0;
>>> }
>>> -static int parse_options(struct fs_context *fc, char *options)
>>> -{
>>> - struct fs_parameter param;
>>> - char *key;
>>> - int ret;
>>> -
>>> - if (!options)
>>> - return 0;
>>> -
>>> - while ((key = strsep(&options, ",")) != NULL) {
>>> - if (*key) {
>>> - size_t v_len = 0;
>>> - char *value = strchr(key, '=');
>>> -
>>> - param.type = fs_value_is_flag;
>>> - param.string = NULL;
>>> -
>>> - if (value) {
>>> - if (value == key)
>>> - continue;
>>> -
>>> - *value++ = 0;
>>> - v_len = strlen(value);
>>> - param.string = kmemdup_nul(value, v_len, GFP_KERNEL);
>>> - if (!param.string)
>>> - return -ENOMEM;
>>> - param.type = fs_value_is_string;
>>> - }
>>> -
>>> - param.key = key;
>>> - param.size = v_len;
>>> -
>>> - ret = f2fs_parse_param(fc, ¶m);
>>> - kfree(param.string);
>>> - if (ret < 0)
>>> - return ret;
>>> - }
>>> - }
>>> - return 0;
>>> -}
>>> -
>>> /*
>>> * Check quota settings consistency.
>>> */
>>> @@ -2583,13 +2542,12 @@ static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi)
>>> f2fs_flush_ckpt_thread(sbi);
>>> }
>>> -static int f2fs_remount(struct super_block *sb, int *flags, char *data)
>>> +static int __f2fs_remount(struct fs_context *fc, struct super_block *sb)
>>> {
>>> struct f2fs_sb_info *sbi = F2FS_SB(sb);
>>> struct f2fs_mount_info org_mount_opt;
>>> - struct f2fs_fs_context ctx;
>>> - struct fs_context fc;
>>> unsigned long old_sb_flags;
>>> + unsigned int flags = fc->sb_flags;
>>> int err;
>>> bool need_restart_gc = false, need_stop_gc = false;
>>> bool need_restart_flush = false, need_stop_flush = false;
>>> @@ -2635,7 +2593,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
>>> #endif
>>> /* recover superblocks we couldn't write due to previous RO mount */
>>> - if (!(*flags & SB_RDONLY) && is_sbi_flag_set(sbi, SBI_NEED_SB_WRITE)) {
>>> + if (!(flags & SB_RDONLY) && is_sbi_flag_set(sbi, SBI_NEED_SB_WRITE)) {
>>> err = f2fs_commit_super(sbi, false);
>>> f2fs_info(sbi, "Try to recover all the superblocks, ret: %d",
>>> err);
>>> @@ -2645,21 +2603,11 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
>>> default_options(sbi, true);
>>> - memset(&fc, 0, sizeof(fc));
>>> - memset(&ctx, 0, sizeof(ctx));
>>> - fc.fs_private = &ctx;
>>> - fc.purpose = FS_CONTEXT_FOR_RECONFIGURE;
>>> -
>>> - /* parse mount options */
>>> - err = parse_options(&fc, data);
>>> - if (err)
>>> - goto restore_opts;
>>> -
>>> - err = f2fs_check_opt_consistency(&fc, sb);
>>> + err = f2fs_check_opt_consistency(fc, sb);
>>> if (err < 0)
>>> goto restore_opts;
>>> - f2fs_apply_options(&fc, sb);
>>> + f2fs_apply_options(fc, sb);
>>> #ifdef CONFIG_BLK_DEV_ZONED
>>> if (f2fs_sb_has_blkzoned(sbi) &&
>>> @@ -2678,20 +2626,20 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
>>> * Previous and new state of filesystem is RO,
>>> * so skip checking GC and FLUSH_MERGE conditions.
>>> */
>>> - if (f2fs_readonly(sb) && (*flags & SB_RDONLY))
>>> + if (f2fs_readonly(sb) && (flags & SB_RDONLY))
>>> goto skip;
>>> - if (f2fs_dev_is_readonly(sbi) && !(*flags & SB_RDONLY)) {
>>> + if (f2fs_dev_is_readonly(sbi) && !(flags & SB_RDONLY)) {
>>> err = -EROFS;
>>> goto restore_opts;
>>> }
>>> #ifdef CONFIG_QUOTA
>>> - if (!f2fs_readonly(sb) && (*flags & SB_RDONLY)) {
>>> + if (!f2fs_readonly(sb) && (flags & SB_RDONLY)) {
>>> err = dquot_suspend(sb, -1);
>>> if (err < 0)
>>> goto restore_opts;
>>> - } else if (f2fs_readonly(sb) && !(*flags & SB_RDONLY)) {
>>> + } else if (f2fs_readonly(sb) && !(flags & SB_RDONLY)) {
>>> /* dquot_resume needs RW */
>>> sb->s_flags &= ~SB_RDONLY;
>>> if (sb_any_quota_suspended(sb)) {
>>> @@ -2747,7 +2695,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
>>> goto restore_opts;
>>> }
>>> - if ((*flags & SB_RDONLY) && test_opt(sbi, DISABLE_CHECKPOINT)) {
>>> + if ((flags & SB_RDONLY) && test_opt(sbi, DISABLE_CHECKPOINT)) {
>>> err = -EINVAL;
>>> f2fs_warn(sbi, "disabling checkpoint not compatible with read-only");
>>> goto restore_opts;
>>> @@ -2758,7 +2706,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
>>> * or if background_gc = off is passed in mount
>>> * option. Also sync the filesystem.
>>> */
>>> - if ((*flags & SB_RDONLY) ||
>>> + if ((flags & SB_RDONLY) ||
>>> (F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_OFF &&
>>> !test_opt(sbi, GC_MERGE))) {
>>> if (sbi->gc_thread) {
>>> @@ -2772,7 +2720,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
>>> need_stop_gc = true;
>>> }
>>> - if (*flags & SB_RDONLY) {
>>> + if (flags & SB_RDONLY) {
>>> sync_inodes_sb(sb);
>>> set_sbi_flag(sbi, SBI_IS_DIRTY);
>>> @@ -2785,7 +2733,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
>>> * We stop issue flush thread if FS is mounted as RO
>>> * or if flush_merge is not passed in mount option.
>>> */
>>> - if ((*flags & SB_RDONLY) || !test_opt(sbi, FLUSH_MERGE)) {
>>> + if ((flags & SB_RDONLY) || !test_opt(sbi, FLUSH_MERGE)) {
>>> clear_opt(sbi, FLUSH_MERGE);
>>> f2fs_destroy_flush_cmd_control(sbi, false);
>>> need_restart_flush = true;
>>> @@ -2827,7 +2775,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
>>> * triggered while remount and we need to take care of it before
>>> * returning from remount.
>>> */
>>> - if ((*flags & SB_RDONLY) || test_opt(sbi, DISABLE_CHECKPOINT) ||
>>> + if ((flags & SB_RDONLY) || test_opt(sbi, DISABLE_CHECKPOINT) ||
>>> !test_opt(sbi, MERGE_CHECKPOINT)) {
>>> f2fs_stop_ckpt_thread(sbi);
>>> } else {
>>> @@ -2854,7 +2802,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
>>> (test_opt(sbi, POSIX_ACL) ? SB_POSIXACL : 0);
>>> limit_reserve_root(sbi);
>>> - *flags = (*flags & ~SB_LAZYTIME) | (sb->s_flags & SB_LAZYTIME);
>>> + fc->sb_flags = (flags & ~SB_LAZYTIME) | (sb->s_flags & SB_LAZYTIME);
>>> sbi->umount_lock_holder = NULL;
>>> return 0;
>>> @@ -3523,7 +3471,6 @@ static const struct super_operations f2fs_sops = {
>>> .freeze_fs = f2fs_freeze,
>>> .unfreeze_fs = f2fs_unfreeze,
>>> .statfs = f2fs_statfs,
>>> - .remount_fs = f2fs_remount,
>>> .shutdown = f2fs_shutdown,
>>> };
>>> @@ -4745,16 +4692,13 @@ static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi)
>>> sbi->readdir_ra = true;
>>> }
>>> -static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
>>> +static int f2fs_fill_super(struct super_block *sb, struct fs_context *fc)
>>> {
>>> struct f2fs_sb_info *sbi;
>>> struct f2fs_super_block *raw_super;
>>> - struct f2fs_fs_context ctx;
>>> - struct fs_context fc;
>>> struct inode *root;
>>> int err;
>>> bool skip_recovery = false, need_fsck = false;
>>> - char *options = NULL;
>>> int recovery, i, valid_super_block;
>>> struct curseg_info *seg_i;
>>> int retry_cnt = 1;
>>> @@ -4767,9 +4711,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
>>> raw_super = NULL;
>>> valid_super_block = -1;
>>> recovery = 0;
>>> - memset(&fc, 0, sizeof(fc));
>>> - memset(&ctx, 0, sizeof(ctx));
>>> - fc.fs_private = &ctx;
>>> /* allocate memory for f2fs-specific super block info */
>>> sbi = kzalloc(sizeof(struct f2fs_sb_info), GFP_KERNEL);
>>> @@ -4820,22 +4761,12 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
>>> sizeof(raw_super->uuid));
>>> default_options(sbi, false);
>>> - /* parse mount options */
>>> - options = kstrdup((const char *)data, GFP_KERNEL);
>>> - if (data && !options) {
>>> - err = -ENOMEM;
>>> - goto free_sb_buf;
>>> - }
>>> -
>>> - err = parse_options(&fc, options);
>>> - if (err)
>>> - goto free_options;
>>> - err = f2fs_check_opt_consistency(&fc, sb);
>>> + err = f2fs_check_opt_consistency(fc, sb);
>>> if (err < 0)
>>> - goto free_options;
>>> + goto free_sb_buf;
>>> - f2fs_apply_options(&fc, sb);
>>> + f2fs_apply_options(fc, sb);
>>> sb->s_maxbytes = max_file_blocks(NULL) <<
>>> le32_to_cpu(raw_super->log_blocksize);
>>> @@ -5160,7 +5091,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
>>> if (err)
>>> goto sync_free_meta;
>>> }
>>> - kvfree(options);
>>> /* recover broken superblock */
>>> if (recovery) {
>>> @@ -5255,7 +5185,6 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
>>> kfree(F2FS_OPTION(sbi).s_qf_names[i]);
>>> #endif
>>> fscrypt_free_dummy_policy(&F2FS_OPTION(sbi).dummy_enc_policy);
>>> - kvfree(options);
>>> free_sb_buf:
>>> kfree(raw_super);
>>> free_sbi:
>>> @@ -5271,14 +5200,39 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
>>> return err;
>>> }
>>> -static struct dentry *f2fs_mount(struct file_system_type *fs_type, int flags,
>>> - const char *dev_name, void *data)
>>> +static int f2fs_get_tree(struct fs_context *fc)
>>> {
>>> - return mount_bdev(fs_type, flags, dev_name, data, f2fs_fill_super);
>>> + return get_tree_bdev(fc, f2fs_fill_super);
>>> +}
>>> +
>>> +static int f2fs_reconfigure(struct fs_context *fc)
>>> +{
>>> + struct super_block *sb = fc->root->d_sb;
>>> +
>>> + return __f2fs_remount(fc, sb);
>>> +}
>>> +
>>> +static void f2fs_fc_free(struct fs_context *fc)
>>> +{
>>> + struct f2fs_fs_context *ctx = fc->fs_private;
>>> + int i;
>>> +
>>> + if (!ctx)
>>> + return;
>>> +
>>> +#ifdef CONFIG_QUOTA
>>> + for (i = 0; i < MAXQUOTAS; i++)
>>> + kfree(F2FS_CTX_INFO(ctx).s_qf_names[i]);
>>> +#endif
>>> + fscrypt_free_dummy_policy(&F2FS_CTX_INFO(ctx).dummy_enc_policy);
>>> + kfree(ctx);
>>> }
>>> static const struct fs_context_operations f2fs_context_ops = {
>>> .parse_param = f2fs_parse_param,
>>> + .get_tree = f2fs_get_tree,
>>> + .reconfigure = f2fs_reconfigure,
>>> + .free = f2fs_fc_free,
>>> };
>>> static void kill_f2fs_super(struct super_block *sb)
>>> @@ -5322,10 +5276,24 @@ static void kill_f2fs_super(struct super_block *sb)
>>> }
>>> }
>>> +static int f2fs_init_fs_context(struct fs_context *fc)
>>> +{
>>> + struct f2fs_fs_context *ctx;
>>> +
>>> + ctx = kzalloc(sizeof(struct f2fs_fs_context), GFP_KERNEL);
>>> + if (!ctx)
>>> + return -ENOMEM;
>>> +
>>> + fc->fs_private = ctx;
>>> + fc->ops = &f2fs_context_ops;
>>> +
>>> + return 0;
>>> +}
>>> +
>>> static struct file_system_type f2fs_fs_type = {
>>> .owner = THIS_MODULE,
>>> .name = "f2fs",
>>> - .mount = f2fs_mount,
>>> + .init_fs_context = f2fs_init_fs_context,
>>> .kill_sb = kill_f2fs_super,
>>> .fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP,
>>> };
>>
next prev parent reply other threads:[~2025-05-14 4:03 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-23 17:08 [PATCH V3 0/7] f2fs: new mount API conversion Eric Sandeen
2025-04-23 17:08 ` [PATCH V3 1/7] f2fs: Add fs parameter specifications for mount options Eric Sandeen
2025-05-08 2:40 ` Hongbo Li
2025-05-08 5:24 ` Chao Yu
2025-07-11 16:30 ` [f2fs-dev] " patchwork-bot+f2fs
2025-04-23 17:08 ` [PATCH V3 2/7] f2fs: move the option parser into handle_mount_opt Eric Sandeen
2025-05-06 20:24 ` Jaegeuk Kim
2025-05-08 5:30 ` Chao Yu
2025-04-23 17:08 ` [PATCH V3 3/7] f2fs: Allow sbi to be NULL in f2fs_printk Eric Sandeen
2025-05-08 5:30 ` Chao Yu
2025-04-23 17:08 ` [PATCH V3 4/7] f2fs: Add f2fs_fs_context to record the mount options Eric Sandeen
2025-05-08 6:34 ` Chao Yu
2025-04-23 17:08 ` [PATCH V3 5/7] f2fs: separate the options parsing and options checking Eric Sandeen
2025-05-06 22:01 ` Jaegeuk Kim
2025-05-06 22:52 ` Eric Sandeen
2025-05-06 23:30 ` Jaegeuk Kim
2025-05-08 8:13 ` Chao Yu
2025-05-08 15:52 ` Eric Sandeen
2025-05-12 3:32 ` Chao Yu
2025-05-14 1:10 ` Hongbo Li
2025-05-14 1:03 ` Hongbo Li
2025-05-13 2:15 ` Jaegeuk Kim
2025-04-23 17:08 ` [PATCH V3 6/7] f2fs: introduce fs_context_operation structure Eric Sandeen
2025-05-08 8:14 ` Chao Yu
2025-04-23 17:08 ` [PATCH V3 7/7] f2fs: switch to the new mount api Eric Sandeen
2025-05-08 9:19 ` Chao Yu
2025-05-08 15:59 ` Eric Sandeen
2025-05-12 3:43 ` Chao Yu
2025-05-13 2:19 ` Eric Sandeen
2025-05-13 2:48 ` Chao Yu
2025-05-13 15:36 ` Jaegeuk Kim
2025-05-13 8:59 ` Chao Yu
2025-05-14 2:33 ` Hongbo Li
2025-05-14 4:03 ` Chao Yu [this message]
2025-05-14 6:15 ` Hongbo Li
2025-05-14 15:30 ` Jaegeuk Kim
2025-05-14 15:46 ` Eric Sandeen
2025-05-15 1:17 ` Hongbo Li
2025-05-16 2:01 ` Hongbo Li
2025-05-16 17:35 ` Jaegeuk Kim
2025-05-19 2:38 ` Hongbo Li
2025-05-13 16:11 ` Jaegeuk Kim
2025-05-06 2:18 ` [PATCH V3 0/7] f2fs: new mount API conversion Eric Sandeen
2025-05-06 16:02 ` Jaegeuk Kim
2025-05-06 22:53 ` Eric Sandeen
2025-05-06 23:55 ` Ian Kent
2025-05-07 0:35 ` Jaegeuk Kim
2025-05-07 0:51 ` Eric Sandeen
2025-05-07 1:23 ` Jaegeuk Kim
2025-05-07 2:56 ` Eric Sandeen
2025-05-07 3:45 ` Eric Sandeen
2025-05-07 14:46 ` Jaegeuk Kim
2025-05-07 17:11 ` Eric Sandeen
2025-05-07 19:48 ` Jaegeuk Kim
2025-05-07 20:19 ` Eric Sandeen
2025-05-07 20:28 ` Jaegeuk Kim
2025-05-07 20:46 ` Eric Sandeen
2025-05-07 21:36 ` Jaegeuk Kim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=979015aa-433d-4057-a454-afaea2c68131@kernel.org \
--to=chao@kernel.org \
--cc=jaegeuk@kernel.org \
--cc=lihongbo22@huawei.com \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=sandeen@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).