From: Chao Yu via Linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>
To: "HONG, Yun" <yhong@link.cuhk.edu.hk>,
"jaegeuk@kernel.org" <jaegeuk@kernel.org>
Cc: "linux-f2fs-devel@lists.sourceforge.net"
<linux-f2fs-devel@lists.sourceforge.net>
Subject: Re: [f2fs-dev] [Crash Report] WARNING in f2fs_init_xattr_caches
Date: Tue, 14 Oct 2025 15:30:09 +0800 [thread overview]
Message-ID: <fcbb431f-f559-447b-b65c-a8efb8c6cf1a@kernel.org> (raw)
In-Reply-To: <TYCP286MB3686EE4EFAC2B76E2812C9B0C1EBA@TYCP286MB3686.JPNP286.PROD.OUTLOOK.COM>
On 10/14/25 15:28, HONG, Yun wrote:
> Hi Chao,
>
> Thanks for the fix. I've tested it on my setup, and the crash no longer occurs with this fix applied.
Hi Hong,
Thanks for the test, let me send a formal patch for fix. :)
Thanks,
>
> Best,
> Yun
> ________________________________
> From: Chao Yu <chao@kernel.org>
> Sent: Monday, October 13, 2025 20:17
> To: HONG, Yun <yhong@link.cuhk.edu.hk>; jaegeuk@kernel.org <jaegeuk@kernel.org>
> Cc: chao@kernel.org <chao@kernel.org>; linux-f2fs-devel@lists.sourceforge.net <linux-f2fs-devel@lists.sourceforge.net>
> Subject: Re: [Crash Report] WARNING in f2fs_init_xattr_caches
>
> Hi Hong,
>
> On 9/29/25 19:43, HONG, Yun wrote:
>> Hi,
>>
>> I would like to kindly report a crash I encountered, identified as "WARNING in f2fs_init_xattr_caches". This issue can be reproduced with a Syzlang reproducer on the mainline version downloaded from https://www.kernel.org/
>> For your convenience, I have included a sample crash report, the configuration file, and a reproduction program as attachments.
>
> Thanks for providing your scripts and images, now I can reproduce this bug.
>
> Could you please help to test below patch?
>
> From 519a1cbfb1f287de5edded596f01a41af0cf25ec Mon Sep 17 00:00:00 2001
> From: Chao Yu <chao@kernel.org>
> Date: Mon, 13 Oct 2025 19:42:36 +0800
> Subject: [PATCH] f2fs: use global inline_xattr_slab instead of per-sb slab
> cache
> MIME-Version: 1.0
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: 8bit
>
> As Hong Yun reported in mailing list:
>
> loop7: detected capacity change from 0 to 131072
> ------------[ cut here ]------------
> kmem_cache of name 'f2fs_xattr_entry-7:7' already exists
> WARNING: CPU: 0 PID: 24426 at mm/slab_common.c:110 kmem_cache_sanity_check mm/slab_common.c:109 [inline]
> WARNING: CPU: 0 PID: 24426 at mm/slab_common.c:110 __kmem_cache_create_args+0xa6/0x320 mm/slab_common.c:307
> CPU: 0 UID: 0 PID: 24426 Comm: syz.7.1370 Not tainted 6.17.0-rc4 #1 PREEMPT(full)
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> RIP: 0010:kmem_cache_sanity_check mm/slab_common.c:109 [inline]
> RIP: 0010:__kmem_cache_create_args+0xa6/0x320 mm/slab_common.c:307
> Call Trace:
> __kmem_cache_create include/linux/slab.h:353 [inline]
> f2fs_kmem_cache_create fs/f2fs/f2fs.h:2943 [inline]
> f2fs_init_xattr_caches+0xa5/0xe0 fs/f2fs/xattr.c:843
> f2fs_fill_super+0x1645/0x2620 fs/f2fs/super.c:4918
> get_tree_bdev_flags+0x1fb/0x260 fs/super.c:1692
> vfs_get_tree+0x43/0x140 fs/super.c:1815
> do_new_mount+0x201/0x550 fs/namespace.c:3808
> do_mount fs/namespace.c:4136 [inline]
> __do_sys_mount fs/namespace.c:4347 [inline]
> __se_sys_mount+0x298/0x2f0 fs/namespace.c:4324
> do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
> do_syscall_64+0x8e/0x3a0 arch/x86/entry/syscall_64.c:94
> entry_SYSCALL_64_after_hwframe+0x76/0x7e
>
> The bug can be reproduced w/ below scripts:
> - mount /dev/vdb /mnt1
> - mount /dev/vdc /mnt2
> - umount /mnt1
> - mounnt /dev/vdb /mnt1
>
> The reason is if we created two slab caches, named f2fs_xattr_entry-7:3
> and f2fs_xattr_entry-7:7, and they have the same slab size. Actually,
> slab system will only create one slab cache core structure which has
> slab name of "f2fs_xattr_entry-7:3", and two slab caches share the same
> structure and cache address.
>
> So, if we destroy f2fs_xattr_entry-7:3 cache w/ cache address, it will
> decrease reference count of slab cache, rather than release slab cache
> entirely, since there is one more user has referenced the cache.
>
> Then, if we try to create slab cache w/ name "f2fs_xattr_entry-7:3" again,
> slab system will find that there is existed cache which has the same name
> and trigger the warning.
>
> Let's changes to use global inline_xattr_slab instead of per-sb slab cache
> for fixing.
>
> Fixes: a999150f4fe3 ("f2fs: use kmem_cache pool during inline xattr lookups")
> Cc: stable@kernel.org
> Reported-by: Hong Yun <yhong@link.cuhk.edu.hk>
> Signed-off-by: Chao Yu <chao@kernel.org>
> ---
> fs/f2fs/f2fs.h | 3 ---
> fs/f2fs/super.c | 17 ++++++++---------
> fs/f2fs/xattr.c | 32 +++++++++++---------------------
> fs/f2fs/xattr.h | 10 ++++++----
> 4 files changed, 25 insertions(+), 37 deletions(-)
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 839032a4da39..c589aed069d9 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -1892,9 +1892,6 @@ struct f2fs_sb_info {
> spinlock_t error_lock; /* protect errors/stop_reason array */
> bool error_dirty; /* errors of sb is dirty */
>
> - struct kmem_cache *inline_xattr_slab; /* inline xattr entry */
> - unsigned int inline_xattr_slab_size; /* default inline xattr slab size */
> -
> /* For reclaimed segs statistics per each GC mode */
> unsigned int gc_segment_mode; /* GC state for reclaimed segments */
> unsigned int gc_reclaimed_segs[MAX_GC_MODE]; /* Reclaimed segs for each mode */
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 6e52e36c1f1a..2ae341768a39 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -2027,7 +2027,6 @@ static void f2fs_put_super(struct super_block *sb)
> kfree(sbi->raw_super);
>
> f2fs_destroy_page_array_cache(sbi);
> - f2fs_destroy_xattr_caches(sbi);
> #ifdef CONFIG_QUOTA
> for (i = 0; i < MAXQUOTAS; i++)
> kfree(F2FS_OPTION(sbi).s_qf_names[i]);
> @@ -5016,13 +5015,9 @@ static int f2fs_fill_super(struct super_block *sb, struct fs_context *fc)
> if (err)
> goto free_iostat;
>
> - /* init per sbi slab cache */
> - err = f2fs_init_xattr_caches(sbi);
> - if (err)
> - goto free_percpu;
> err = f2fs_init_page_array_cache(sbi);
> if (err)
> - goto free_xattr_cache;
> + goto free_percpu;
>
> /* get an inode for meta space */
> sbi->meta_inode = f2fs_iget(sb, F2FS_META_INO(sbi));
> @@ -5351,8 +5346,6 @@ static int f2fs_fill_super(struct super_block *sb, struct fs_context *fc)
> sbi->meta_inode = NULL;
> free_page_array_cache:
> f2fs_destroy_page_array_cache(sbi);
> -free_xattr_cache:
> - f2fs_destroy_xattr_caches(sbi);
> free_percpu:
> destroy_percpu_info(sbi);
> free_iostat:
> @@ -5555,10 +5548,15 @@ static int __init init_f2fs_fs(void)
> err = f2fs_create_casefold_cache();
> if (err)
> goto free_compress_cache;
> - err = register_filesystem(&f2fs_fs_type);
> + err = f2fs_init_xattr_cache();
> if (err)
> goto free_casefold_cache;
> + err = register_filesystem(&f2fs_fs_type);
> + if (err)
> + goto free_xattr_cache;
> return 0;
> +free_xattr_cache:
> + f2fs_destroy_xattr_cache();
> free_casefold_cache:
> f2fs_destroy_casefold_cache();
> free_compress_cache:
> @@ -5599,6 +5597,7 @@ static int __init init_f2fs_fs(void)
> static void __exit exit_f2fs_fs(void)
> {
> unregister_filesystem(&f2fs_fs_type);
> + f2fs_destroy_xattr_cache();
> f2fs_destroy_casefold_cache();
> f2fs_destroy_compress_cache();
> f2fs_destroy_compress_mempool();
> diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c
> index 58632a2b6613..9f20b67e90d1 100644
> --- a/fs/f2fs/xattr.c
> +++ b/fs/f2fs/xattr.c
> @@ -23,11 +23,12 @@
> #include "xattr.h"
> #include "segment.h"
>
> +struct kmem_cache *inline_xattr_slab;
> static void *xattr_alloc(struct f2fs_sb_info *sbi, int size, bool *is_inline)
> {
> - if (likely(size == sbi->inline_xattr_slab_size)) {
> + if (likely(size == DEFAULT_XATTR_SLAB_SIZE)) {
> *is_inline = true;
> - return f2fs_kmem_cache_alloc(sbi->inline_xattr_slab,
> + return f2fs_kmem_cache_alloc(inline_xattr_slab,
> GFP_F2FS_ZERO, false, sbi);
> }
> *is_inline = false;
> @@ -38,7 +39,7 @@ static void xattr_free(struct f2fs_sb_info *sbi, void *xattr_addr,
> bool is_inline)
> {
> if (is_inline)
> - kmem_cache_free(sbi->inline_xattr_slab, xattr_addr);
> + kmem_cache_free(inline_xattr_slab, xattr_addr);
> else
> kfree(xattr_addr);
> }
> @@ -830,25 +831,14 @@ int f2fs_setxattr(struct inode *inode, int index, const char *name,
> return err;
> }
>
> -int f2fs_init_xattr_caches(struct f2fs_sb_info *sbi)
> +int __init f2fs_init_xattr_cache(void)
> {
> - dev_t dev = sbi->sb->s_bdev->bd_dev;
> - char slab_name[32];
> -
> - sprintf(slab_name, "f2fs_xattr_entry-%u:%u", MAJOR(dev), MINOR(dev));
> -
> - sbi->inline_xattr_slab_size = F2FS_OPTION(sbi).inline_xattr_size *
> - sizeof(__le32) + XATTR_PADDING_SIZE;
> -
> - sbi->inline_xattr_slab = f2fs_kmem_cache_create(slab_name,
> - sbi->inline_xattr_slab_size);
> - if (!sbi->inline_xattr_slab)
> - return -ENOMEM;
> -
> - return 0;
> + inline_xattr_slab = f2fs_kmem_cache_create("f2fs_xattr_entry",
> + DEFAULT_XATTR_SLAB_SIZE);
> + return inline_xattr_slab ? 0 : -ENOMEM;
> }
>
> -void f2fs_destroy_xattr_caches(struct f2fs_sb_info *sbi)
> +void f2fs_destroy_xattr_cache(void)
> {
> - kmem_cache_destroy(sbi->inline_xattr_slab);
> -}
> + kmem_cache_destroy(inline_xattr_slab);
> +}
> \ No newline at end of file
> diff --git a/fs/f2fs/xattr.h b/fs/f2fs/xattr.h
> index 4fc0b2305fbd..9acf62541a71 100644
> --- a/fs/f2fs/xattr.h
> +++ b/fs/f2fs/xattr.h
> @@ -89,6 +89,8 @@ struct f2fs_xattr_entry {
> F2FS_TOTAL_EXTRA_ATTR_SIZE / sizeof(__le32) - \
> DEF_INLINE_RESERVED_SIZE - \
> MIN_INLINE_DENTRY_SIZE / sizeof(__le32))
> +#define DEFAULT_XATTR_SLAB_SIZE (DEFAULT_INLINE_XATTR_ADDRS * \
> + sizeof(__le32) + XATTR_PADDING_SIZE)
>
> /*
> * On-disk structure of f2fs_xattr
> @@ -132,8 +134,8 @@ int f2fs_setxattr(struct inode *, int, const char *, const void *,
> int f2fs_getxattr(struct inode *, int, const char *, void *,
> size_t, struct folio *);
> ssize_t f2fs_listxattr(struct dentry *, char *, size_t);
> -int f2fs_init_xattr_caches(struct f2fs_sb_info *);
> -void f2fs_destroy_xattr_caches(struct f2fs_sb_info *);
> +int __init f2fs_init_xattr_cache(void);
> +void f2fs_destroy_xattr_cache(void);
> #else
>
> #define f2fs_xattr_handlers NULL
> @@ -150,8 +152,8 @@ static inline int f2fs_getxattr(struct inode *inode, int index,
> {
> return -EOPNOTSUPP;
> }
> -static inline int f2fs_init_xattr_caches(struct f2fs_sb_info *sbi) { return 0; }
> -static inline void f2fs_destroy_xattr_caches(struct f2fs_sb_info *sbi) { }
> +static int __init f2fs_init_xattr_cache(void) { return 0; }
> +static void f2fs_destroy_xattr_cache(void) { }
> #endif
>
> #ifdef CONFIG_F2FS_FS_SECURITY
> --
> 2.49.0
>
>
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
prev parent reply other threads:[~2025-10-14 7:30 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <TYCP286MB3686D500C8AF350E0BE8B4F2C11BA@TYCP286MB3686.JPNP286.PROD.OUTLOOK.COM>
2025-10-10 7:16 ` [f2fs-dev] [Crash Report] WARNING in f2fs_init_xattr_caches Chao Yu via Linux-f2fs-devel
2025-10-13 12:17 ` Chao Yu via Linux-f2fs-devel
[not found] ` <TYCP286MB3686EE4EFAC2B76E2812C9B0C1EBA@TYCP286MB3686.JPNP286.PROD.OUTLOOK.COM>
2025-10-14 7:30 ` Chao Yu via Linux-f2fs-devel [this message]
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=fcbb431f-f559-447b-b65c-a8efb8c6cf1a@kernel.org \
--to=linux-f2fs-devel@lists.sourceforge.net \
--cc=chao@kernel.org \
--cc=jaegeuk@kernel.org \
--cc=yhong@link.cuhk.edu.hk \
/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).