+++ /dev/null
-From 190a3e3cce2680c50605abdac3275b70415585fe Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 23 May 2023 11:58:22 +0800
-Subject: f2fs: don't reset unchangable mount option in f2fs_remount()
-
-From: Chao Yu <chao@kernel.org>
-
-[ Upstream commit 458c15dfbce62c35fefd9ca637b20a051309c9f1 ]
-
-syzbot reports a bug as below:
-
-general protection fault, probably for non-canonical address 0xdffffc0000000009: 0000 [#1] PREEMPT SMP KASAN
-RIP: 0010:__lock_acquire+0x69/0x2000 kernel/locking/lockdep.c:4942
-Call Trace:
- lock_acquire+0x1e3/0x520 kernel/locking/lockdep.c:5691
- __raw_write_lock include/linux/rwlock_api_smp.h:209 [inline]
- _raw_write_lock+0x2e/0x40 kernel/locking/spinlock.c:300
- __drop_extent_tree+0x3ac/0x660 fs/f2fs/extent_cache.c:1100
- f2fs_drop_extent_tree+0x17/0x30 fs/f2fs/extent_cache.c:1116
- f2fs_insert_range+0x2d5/0x3c0 fs/f2fs/file.c:1664
- f2fs_fallocate+0x4e4/0x6d0 fs/f2fs/file.c:1838
- vfs_fallocate+0x54b/0x6b0 fs/open.c:324
- ksys_fallocate fs/open.c:347 [inline]
- __do_sys_fallocate fs/open.c:355 [inline]
- __se_sys_fallocate fs/open.c:353 [inline]
- __x64_sys_fallocate+0xbd/0x100 fs/open.c:353
- do_syscall_x64 arch/x86/entry/common.c:50 [inline]
- do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
- entry_SYSCALL_64_after_hwframe+0x63/0xcd
-
-The root cause is race condition as below:
-- since it tries to remount rw filesystem, so that do_remount won't
-call sb_prepare_remount_readonly to block fallocate, there may be race
-condition in between remount and fallocate.
-- in f2fs_remount(), default_options() will reset mount option to default
-one, and then update it based on result of parse_options(), so there is
-a hole which race condition can happen.
-
-Thread A Thread B
-- f2fs_fill_super
- - parse_options
- - clear_opt(READ_EXTENT_CACHE)
-
-- f2fs_remount
- - default_options
- - set_opt(READ_EXTENT_CACHE)
- - f2fs_fallocate
- - f2fs_insert_range
- - f2fs_drop_extent_tree
- - __drop_extent_tree
- - __may_extent_tree
- - test_opt(READ_EXTENT_CACHE) return true
- - write_lock(&et->lock) access NULL pointer
- - parse_options
- - clear_opt(READ_EXTENT_CACHE)
-
-Cc: <stable@vger.kernel.org>
-Reported-by: syzbot+d015b6c2fbb5c383bf08@syzkaller.appspotmail.com
-Closes: https://lore.kernel.org/linux-f2fs-devel/20230522124203.3838360-1-chao@kernel.org
-Signed-off-by: Chao Yu <chao@kernel.org>
-Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/f2fs/super.c | 30 ++++++++++++++++++------------
- 1 file changed, 18 insertions(+), 12 deletions(-)
-
-diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
-index 36bb1c969e8bb..ff47aad636e5b 100644
---- a/fs/f2fs/super.c
-+++ b/fs/f2fs/super.c
-@@ -2040,9 +2040,22 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
- return 0;
- }
-
--static void default_options(struct f2fs_sb_info *sbi)
-+static void default_options(struct f2fs_sb_info *sbi, bool remount)
- {
- /* init some FS parameters */
-+ if (!remount) {
-+ set_opt(sbi, READ_EXTENT_CACHE);
-+ clear_opt(sbi, DISABLE_CHECKPOINT);
-+
-+ if (f2fs_hw_support_discard(sbi) || f2fs_hw_should_discard(sbi))
-+ set_opt(sbi, DISCARD);
-+
-+ if (f2fs_sb_has_blkzoned(sbi))
-+ F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_SECTION;
-+ else
-+ F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_BLOCK;
-+ }
-+
- if (f2fs_sb_has_readonly(sbi))
- F2FS_OPTION(sbi).active_logs = NR_CURSEG_RO_TYPE;
- else
-@@ -2065,23 +2078,16 @@ static void default_options(struct f2fs_sb_info *sbi)
- set_opt(sbi, INLINE_XATTR);
- set_opt(sbi, INLINE_DATA);
- set_opt(sbi, INLINE_DENTRY);
-- set_opt(sbi, READ_EXTENT_CACHE);
- set_opt(sbi, NOHEAP);
-- clear_opt(sbi, DISABLE_CHECKPOINT);
- set_opt(sbi, MERGE_CHECKPOINT);
- F2FS_OPTION(sbi).unusable_cap = 0;
- sbi->sb->s_flags |= SB_LAZYTIME;
- if (!f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb))
- set_opt(sbi, FLUSH_MERGE);
-- if (f2fs_hw_support_discard(sbi) || f2fs_hw_should_discard(sbi))
-- set_opt(sbi, DISCARD);
-- if (f2fs_sb_has_blkzoned(sbi)) {
-+ if (f2fs_sb_has_blkzoned(sbi))
- F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS;
-- F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_SECTION;
-- } else {
-+ else
- F2FS_OPTION(sbi).fs_mode = FS_MODE_ADAPTIVE;
-- F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_BLOCK;
-- }
-
- #ifdef CONFIG_F2FS_FS_XATTR
- set_opt(sbi, XATTR_USER);
-@@ -2253,7 +2259,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
- clear_sbi_flag(sbi, SBI_NEED_SB_WRITE);
- }
-
-- default_options(sbi);
-+ default_options(sbi, true);
-
- /* parse mount options */
- err = parse_options(sb, data, true);
-@@ -4150,7 +4156,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
- sbi->s_chksum_seed = f2fs_chksum(sbi, ~0, raw_super->uuid,
- sizeof(raw_super->uuid));
-
-- default_options(sbi);
-+ default_options(sbi, false);
- /* parse mount options */
- options = kstrdup((const char *)data, GFP_KERNEL);
- if (data && !options) {
---
-2.39.2
-
+++ /dev/null
-From 3345346778c41ffe5a9c6e5e52a99632d6c1518d Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 10 Nov 2022 17:15:01 +0800
-Subject: f2fs: fix to set flush_merge opt and show noflush_merge
-
-From: Yangtao Li <frank.li@vivo.com>
-
-[ Upstream commit 967eaad1fed5f6335ea97a47d45214744dc57925 ]
-
-Some minor modifications to flush_merge and related parameters:
-
- 1.The FLUSH_MERGE opt is set by default only in non-ro mode.
- 2.When ro and merge are set at the same time, an error is reported.
- 3.Display noflush_merge mount opt.
-
-Suggested-by: Chao Yu <chao@kernel.org>
-Signed-off-by: Yangtao Li <frank.li@vivo.com>
-Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-Stable-dep-of: 458c15dfbce6 ("f2fs: don't reset unchangable mount option in f2fs_remount()")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/f2fs/super.c | 13 +++++++++++--
- 1 file changed, 11 insertions(+), 2 deletions(-)
-
-diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
-index b6dad389fa144..36bb1c969e8bb 100644
---- a/fs/f2fs/super.c
-+++ b/fs/f2fs/super.c
-@@ -1347,6 +1347,12 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
- return -EINVAL;
- }
-
-+ if ((f2fs_sb_has_readonly(sbi) || f2fs_readonly(sbi->sb)) &&
-+ test_opt(sbi, FLUSH_MERGE)) {
-+ f2fs_err(sbi, "FLUSH_MERGE not compatible with readonly mode");
-+ return -EINVAL;
-+ }
-+
- if (f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb)) {
- f2fs_err(sbi, "Allow to mount readonly mode only");
- return -EROFS;
-@@ -1933,8 +1939,10 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
- seq_puts(seq, ",inline_dentry");
- else
- seq_puts(seq, ",noinline_dentry");
-- if (!f2fs_readonly(sbi->sb) && test_opt(sbi, FLUSH_MERGE))
-+ if (test_opt(sbi, FLUSH_MERGE))
- seq_puts(seq, ",flush_merge");
-+ else
-+ seq_puts(seq, ",noflush_merge");
- if (test_opt(sbi, NOBARRIER))
- seq_puts(seq, ",nobarrier");
- if (test_opt(sbi, FASTBOOT))
-@@ -2063,7 +2071,8 @@ static void default_options(struct f2fs_sb_info *sbi)
- set_opt(sbi, MERGE_CHECKPOINT);
- F2FS_OPTION(sbi).unusable_cap = 0;
- sbi->sb->s_flags |= SB_LAZYTIME;
-- set_opt(sbi, FLUSH_MERGE);
-+ if (!f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb))
-+ set_opt(sbi, FLUSH_MERGE);
- if (f2fs_hw_support_discard(sbi) || f2fs_hw_should_discard(sbi))
- set_opt(sbi, DISCARD);
- if (f2fs_sb_has_blkzoned(sbi)) {
---
-2.39.2
-