From patchwork Wed Aug 14 02:39:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hongbo Li X-Patchwork-Id: 13762760 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.105.38.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3DBD7C52D7C for ; Wed, 14 Aug 2024 02:32:54 +0000 (UTC) Received: from [127.0.0.1] (helo=sfs-ml-3.v29.lw.sourceforge.com) by sfs-ml-3.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1se3oi-0007GY-Tr; Wed, 14 Aug 2024 02:32:52 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-3.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1se3oh-0007GP-9B for linux-f2fs-devel@lists.sourceforge.net; Wed, 14 Aug 2024 02:32:50 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Type:Content-Transfer-Encoding:MIME-Version :References:In-Reply-To:Message-ID:Date:Subject:CC:To:From:Sender:Reply-To: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=L5+3pgh7XcGJ/LM02oQSgPdOPS26o8JoFqgoxuK4z18=; b=ORZTurk/oCqge0jI0omVrD7+nb 2zk1UTo0x2H+hu/2+/wRTg/3sFG++lDaHAQFcIMl1lCcVpxrhCbOpr1q3zc1ix5VqYL9mKGUmizt3 88e+HxbcLcFW8C94sMA7gofC+RSSumqDB8H4251VAFSS3aGYuxZSNWxoBw8HFjMYedBg=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Type:Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:CC:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=L5+3pgh7XcGJ/LM02oQSgPdOPS26o8JoFqgoxuK4z18=; b=ZkP3YZ6KSv056ttIwqean0rI4V LCQctsu6K5Nm/E6nO3UEbDjq7ARDMpyIXfurVSF6XSECaYMG842TRTUG62xoKi6Z2TCZwy5eTVIYd 6WjQQFovNwSJ+6ZXYhgSyDbBzb9j9kwmzz3LIGO35S66ChXepNVMSCuaw3kpXyogV38w=; Received: from szxga02-in.huawei.com ([45.249.212.188]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1se3od-0005V3-VL for linux-f2fs-devel@lists.sourceforge.net; Wed, 14 Aug 2024 02:32:50 +0000 Received: from mail.maildlp.com (unknown [172.19.163.252]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4WkC0f62CyzfbQk; Wed, 14 Aug 2024 10:30:42 +0800 (CST) Received: from dggpeml500022.china.huawei.com (unknown [7.185.36.66]) by mail.maildlp.com (Postfix) with ESMTPS id DFF4F180088; Wed, 14 Aug 2024 10:32:39 +0800 (CST) Received: from huawei.com (10.90.53.73) by dggpeml500022.china.huawei.com (7.185.36.66) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.39; Wed, 14 Aug 2024 10:32:39 +0800 To: , Date: Wed, 14 Aug 2024 10:39:11 +0800 Message-ID: <20240814023912.3959299-9-lihongbo22@huawei.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240814023912.3959299-1-lihongbo22@huawei.com> References: <20240814023912.3959299-1-lihongbo22@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.90.53.73] X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To dggpeml500022.china.huawei.com (7.185.36.66) X-Headers-End: 1se3od-0005V3-VL Subject: [f2fs-dev] [PATCH 8/9] f2fs: switch to the new mount api X-BeenThere: linux-f2fs-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Hongbo Li via Linux-f2fs-devel From: Hongbo Li Reply-To: Hongbo Li Cc: linux-fsdevel@vger.kernel.org, lczerner@redhat.com, brauner@kernel.org, lihongbo22@huawei.com, linux-f2fs-devel@lists.sourceforge.net Errors-To: linux-f2fs-devel-bounces@lists.sourceforge.net The new mount api will excute .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. Signed-off-by: Hongbo Li --- fs/f2fs/super.c | 125 ++++++++++++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 53 deletions(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 8c43fbe092ff..86acb7354d95 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2953,13 +2953,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; @@ -2976,6 +2975,11 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) int i, j; #endif + /* check the mount options legality in ctx first */ + err = f2fs_validate_options(fc); + if (err) + return -EINVAL; + /* * Save the old mount options in case we * need to restore them. @@ -3002,7 +3006,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); @@ -3012,21 +3016,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) && @@ -3046,20 +3040,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)) { @@ -3109,7 +3103,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; @@ -3120,7 +3114,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) { @@ -3134,7 +3128,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); @@ -3147,7 +3141,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; @@ -3188,7 +3182,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 { @@ -3216,7 +3210,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) limit_reserve_root(sbi); adjust_unusable_cap_perc(sbi); - *flags = (*flags & ~SB_LAZYTIME) | (sb->s_flags & SB_LAZYTIME); + fc->sb_flags = (flags & ~SB_LAZYTIME) | (sb->s_flags & SB_LAZYTIME); return 0; restore_checkpoint: if (need_enable_checkpoint) { @@ -3863,7 +3857,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, }; @@ -5047,16 +5040,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; @@ -5069,9 +5059,11 @@ 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; + + /* check the mount options legality in ctx first */ + err = f2fs_validate_options(fc); + if (err) + return -EINVAL; /* allocate memory for f2fs-specific super block info */ sbi = kzalloc(sizeof(struct f2fs_sb_info), GFP_KERNEL); @@ -5131,22 +5123,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); @@ -5460,7 +5442,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) { @@ -5553,7 +5534,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: @@ -5571,14 +5551,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) @@ -5620,10 +5625,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, };