Re: PROBLEM: FUSE_NOTIFY_INVAL_ENTRY leaves stale negative dentry after c9ba789dad15

From: Miklos Szeredi

Date: Mon Jun 01 2026 - 04:35:43 EST


[Cc: Neil]

On Sun, 31 May 2026 at 03:12, Артем Лабазов <123321artyom@xxxxxxxxx> wrote:
>
> Hi,
>
> I am reporting a FUSE/VFS regression introduced by:
>
> c9ba789dad15ba65662bba17595c0aeaa0cfcf1c
> VFS: introduce start_creating_noperm() and start_removing_noperm()
>
> After a FUSE filesystem returns a cached negative lookup for a name, then
> later makes that name visible and sends FUSE_NOTIFY_INVAL_ENTRY for it,
> readdir() can list the entry while stat()/open() on the same path still
> returns ENOENT.
>
> Bisect result:
>
> good: v6.17
> bad: v6.19
>
> first bad commit:
> c9ba789dad15ba65662bba17595c0aeaa0cfcf1c
> VFS: introduce start_creating_noperm() and start_removing_noperm()
>
> Adjacent commits:
>
> bd6ede8a06e89ca5a94a8b51cea792705d1b8ca2 GOOD
> c9ba789dad15ba65662bba17595c0aeaa0cfcf1c BAD
>
> The bad commit changes fs/fuse/dir.c:fuse_reverse_inval_entry() to use
> start_removing_noperm().
>
> I attached a minimal libfuse3 reproducer. It does:
>
> 1. lookup("config") returns ino=0 with non-zero entry_timeout, causing
> the kernel to cache a negative dentry.
> 2. The filesystem makes "config" visible.
> 3. It calls fuse_lowlevel_notify_inval_entry(root, "config").
> 4. The test checks whether readdir lists "config" and stat("config")
> succeeds.

Yeah, issue is that start_removing_* all work on a POSITIVE dentry.

FUSE_NOTIFY_INVAL_ENTRY works on both positive and negative dentries,
doesn't care about the inode (or lack of it) at all.

I've not dug myself into this work, so not sure what the concept here
is, or how this should be fixed, but this is definitely not (just) a
removal op.

Thanks,
Miklos


>
> Build:
>
> cc -O2 -Wall -Wextra repro.c -o repro $(pkg-config --cflags --libs
> fuse3) -lpthread
>
> Run:
>
> mkdir -p mnt
> ./repro ./mnt
>
> Observed results:
>
> Linux 6.17.0:
> notify_inval_entry rc=0
> listed=1 stat=OK
> GOOD
> exit code 0
>
> Linux 6.19.0:
> notify_inval_entry rc=-2
> listed=1 stat=No such file or directory
> BAD
> exit code 1
>
> Linux 7.1.0-rc5-00426-g670b77dfebe7:
> notify_inval_entry rc=-2
> listed=1 stat=No such file or directory
> BAD
> exit code 1
>
> #regzbot introduced: c9ba789dad15ba65662bba17595c0aeaa0cfcf1c
>
> Assisted-by: OpenCode:openai/gpt-5.5
>
> Thanks,
> Artem