Re: [syzbot] [gfs2?] WARNING in filename_mkdirat
From: NeilBrown
Date: Thu Feb 19 2026 - 16:46:09 EST
[gfs2 maintainer an list added - Hi Andreas!]
On Thu, 19 Feb 2026, Christian Brauner wrote:
> On Wed, Feb 18, 2026 at 09:18:53AM +1100, NeilBrown wrote:
> > On Tue, 17 Feb 2026, NeilBrown wrote:
> > > On Tue, 17 Feb 2026, Christian Brauner wrote:
> > > > On Mon, Feb 16, 2026 at 04:30:27PM -0800, syzbot wrote:
> > > > > Hello,
> > > > >
> > > > > syzbot found the following issue on:
> > > > >
> > > > > HEAD commit: 0f2acd3148e0 Merge tag 'm68knommu-for-v7.0' of git://git.k..
> > > > > git tree: upstream
> > > > > console output: https://syzkaller.appspot.com/x/log.txt?x=15331c02580000
> > > > > kernel config: https://syzkaller.appspot.com/x/.config?x=ac00553de86d6bf0
> > > > > dashboard link: https://syzkaller.appspot.com/bug?extid=0ea5108a1f5fb4fcc2d8
> > > > > compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
> > > > > syz repro: https://syzkaller.appspot.com/x/repro.syz?x=146b295a580000
> > > > >
> > > > > Downloadable assets:
> > > > > disk image (non-bootable): https://storage.googleapis.com/syzbot-assets/d900f083ada3/non_bootable_disk-0f2acd31.raw.xz
> > > > > vmlinux: https://storage.googleapis.com/syzbot-assets/b7d134e71e9c/vmlinux-0f2acd31.xz
> > > > > kernel image: https://storage.googleapis.com/syzbot-assets/b18643058ceb/bzImage-0f2acd31.xz
> > > > > mounted in repro: https://storage.googleapis.com/syzbot-assets/bbfed09077d3/mount_1.gz
> > > > > fsck result: OK (log: https://syzkaller.appspot.com/x/fsck.log?x=106b295a580000)
> > > > >
> > > > > IMPORTANT: if you fix the issue, please add the following tag to the commit:
> > > > > Reported-by: syzbot+0ea5108a1f5fb4fcc2d8@xxxxxxxxxxxxxxxxxxxxxxxxx
> > > >
> > > > Neil, is this something you have time to look into?
> > >
> > > The reproducer appears to mount a gfs2 filesystem and mkdir 3
> > > directories:
> > > ./file1
> > > ./file1/file4
> > > ./file1/file4/file7
> > >
> > > and somewhere in there it crashes because vfs_mkdir() returns a
> > > non-error dentry for which ->d_parent->d_inode is not locked and
> > > end_creating_path() tries to up_write().
> > >
> > > Presumably either ->d_parent has changed or the inode was unlocked?
> > >
> > > gfs2_mkdir() never returns a dentry, so it must be returning NULL.
> > >
> > > It's weird - but that is no surprise.
> > >
> > > I'll try building a kernel myself and see if the reproducer still fires.
> > > if so some printk tracing my reveal something.
> >
> > Unfortunately that didn't work out.
> > Using the provided vmlinux and root image and repro, and a syzkaller I
> > compiled from current git, I cannot trigger the crash.
> >
> > I'll have another look at the code but I don't hold out a lot of hope.
>
> There's at least a proper C repro now.
>
Yes - and with the new C repro I can trigger the bug.
The problem is in gfs2. gfs2_create_inode() calls d_instantiate()
before unlock_new_inode(). This is bad. d_instantiate_new() should be
used, which makes sure the two things happen in the correct order.
Key to understanding the problem is knowing that unlock_new_inode()
calls lockdep_annotate_inode_mutex_key() which (potentially) calls
init_rwsem(&inode->i_rwsem);
So if anyone has locked the inode before unlock_new_inode() is called,
the lock is lost when i_rwsem is reinitialised.
The reproducer calls mkdir("a") and mkdir("a/b") concurrently from
separate threads. The second mkdir() often fails (I assume) because "a"
cannot be found. But if that second mkdir() runs just after gfs2 has
called d_instantiate(), then the lookup of "a" will succeed and so the
inode will be locked ready for mkdir.. Then the mkdir("a") completes
calling unlock_new_inode() which reinitialised i_rwsem. When
mkdir("a/b") comes to lock the parent, it finds that it isn't locked any
more.
There is non-trivial code between the d_instantiate() call and the
unlock_new_inode() call which I do not understand. So I will not
propose a patch. I don't know if that code should be after
d_instantiate_new(), or before it.
So I'll leave that to Andreas.
Thanks,
NeilBrown