linux-f2fs-devel.lists.sourceforge.net archive mirror
 help / color / mirror / Atom feed
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

      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).