+++ /dev/null
-From 7af2ae1b1531feab5d38ec9c8f472dc6cceb4606 Mon Sep 17 00:00:00 2001
-From: Christian Brauner <brauner@kernel.org>
-Date: Fri, 19 Apr 2024 20:36:11 +0800
-Subject: erofs: reliably distinguish block based and fscache mode
-
-From: Christian Brauner <brauner@kernel.org>
-
-commit 7af2ae1b1531feab5d38ec9c8f472dc6cceb4606 upstream.
-
-When erofs_kill_sb() is called in block dev based mode, s_bdev may not
-have been initialised yet, and if CONFIG_EROFS_FS_ONDEMAND is enabled,
-it will be mistaken for fscache mode, and then attempt to free an anon_dev
-that has never been allocated, triggering the following warning:
-
-============================================
-ida_free called for id=0 which is not allocated.
-WARNING: CPU: 14 PID: 926 at lib/idr.c:525 ida_free+0x134/0x140
-Modules linked in:
-CPU: 14 PID: 926 Comm: mount Not tainted 6.9.0-rc3-dirty #630
-RIP: 0010:ida_free+0x134/0x140
-Call Trace:
- <TASK>
- erofs_kill_sb+0x81/0x90
- deactivate_locked_super+0x35/0x80
- get_tree_bdev+0x136/0x1e0
- vfs_get_tree+0x2c/0xf0
- do_new_mount+0x190/0x2f0
- [...]
-============================================
-
-Now when erofs_kill_sb() is called, erofs_sb_info must have been
-initialised, so use sbi->fsid to distinguish between the two modes.
-
-Signed-off-by: Christian Brauner <brauner@kernel.org>
-Signed-off-by: Baokun Li <libaokun1@huawei.com>
-Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com>
-Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
-Reviewed-by: Chao Yu <chao@kernel.org>
-Link: https://lore.kernel.org/r/20240419123611.947084-3-libaokun1@huawei.com
-Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
-Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- fs/erofs/super.c | 8 ++------
- 1 file changed, 2 insertions(+), 6 deletions(-)
-
---- a/fs/erofs/super.c
-+++ b/fs/erofs/super.c
-@@ -892,7 +892,7 @@ static int erofs_init_fs_context(struct
- */
- static void erofs_kill_sb(struct super_block *sb)
- {
-- struct erofs_sb_info *sbi;
-+ struct erofs_sb_info *sbi = EROFS_SB(sb);
-
- WARN_ON(sb->s_magic != EROFS_SUPER_MAGIC);
-
-@@ -902,15 +902,11 @@ static void erofs_kill_sb(struct super_b
- return;
- }
-
-- if (erofs_is_fscache_mode(sb))
-+ if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && sbi->fsid)
- kill_anon_super(sb);
- else
- kill_block_super(sb);
-
-- sbi = EROFS_SB(sb);
-- if (!sbi)
-- return;
--
- erofs_free_dev_context(sbi->devs);
- fs_put_dax(sbi->dax_dev, NULL);
- erofs_fscache_unregister_fs(sb);