Re: [PATCH] fuse: fix conversion of fuse_reverse_inval_entry() to start_removing()

Miklos Szeredi <[email protected]>
Newsgroups org.kernel.vger.ecryptfs,dev.linux.lists.netfs,org.kernel.vger.linux-cifs,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-nfs,org.kernel.vger.linux-security-module,org.kernel.vger.linux-unionfs,org.kernel.vger.linux-xfs,org.kernel.vger.selinux
Message-ID <CAJfpegs+o01jgY76WsGnk9j41LS5V0JQSk--d6xsJJp4VjTh8Q@mail.gmail.com>
On Mon, 1 Dec 2025 at 09:33, Al Viro <[email protected]> wrote:
>
> On Mon, Dec 01, 2025 at 09:22:54AM +0100, Amir Goldstein wrote:
>
> > I don't think there is a point in optimizing parallel dir operations
> > with FUSE server cache invalidation, but maybe I am missing
> > something.
>
> The interesting part is the expected semantics of operation;
> d_invalidate() side definitely doesn't need any of that cruft,
> but I would really like to understand what that function
> is supposed to do.
>
> Miklos, could you post a brain dump on that?

This function is supposed to invalidate a dentry due to remote changes
(FUSE_NOTIFY_INVAL_ENTRY).  Originally it was supplied a parent ID and
a name and called d_invalidate() on the looked up dentry.

Then it grew a variant (FUSE_NOTIFY_DELETE) that was also supplied a
child ID, which was matched against the looked up inode.  This was
commit 451d0f599934 ("FUSE: Notifying the kernel of deletion."),
Apparently this worked around the fact that at that time
d_invalidate() returned -EBUSY if the target was still in use and
didn't unhash the dentry in that case.

That was later changed by commit bafc9b754f75 ("vfs: More precise
tests in d_invalidate") to unconditionally unhash the target, which
effectively made FUSE_NOTIFY_INVAL_ENTRY and FUSE_NOTIFY_DELETE
equivalent and the code in question unnecessary.

For the future, we could also introduce FUSE_NOTIFY_MOVE, that would
differentiate between a delete and a move, while
FUSE_NOTIFY_INVAL_ENTRY would continue to be the common (deleted or
moved) notification.

Attaching untested patch to remove this cruft.

Thanks,
Miklos
fuse-notify_inval_entry-and-notify_delete-are-equivalent.patch (text/x-patch, 1022 B)
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index ecaec0fea3a1..d9dffc326a26 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1417,34 +1417,9 @@ int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid,
 		d_invalidate(entry);
 	fuse_invalidate_entry_cache(entry);
 
-	if (child_nodeid != 0 && d_really_is_positive(entry)) {
-		inode_lock(d_inode(entry));
-		if (get_node_id(d_inode(entry)) != child_nodeid) {
-			err = -ENOENT;
-			goto badentry;
-		}
-		if (d_mountpoint(entry)) {
-			err = -EBUSY;
-			goto badentry;
-		}
-		if (d_is_dir(entry)) {
-			shrink_dcache_parent(entry);
-			if (!simple_empty(entry)) {
-				err = -ENOTEMPTY;
-				goto badentry;
-			}
-			d_inode(entry)->i_flags |= S_DEAD;
-		}
-		dont_mount(entry);
-		clear_nlink(d_inode(entry));
-		err = 0;
- badentry:
-		inode_unlock(d_inode(entry));
-		if (!err)
-			d_delete(entry);
-	} else {
-		err = 0;
-	}
+	err = 0;
+	if (child_nodeid != 0 && get_node_id(d_inode(entry)) != child_nodeid)
+		err = -ENOENT;
 	dput(entry);
 
  unlock:
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.