]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Revert "fuse: fix conversion of fuse_reverse_inval_entry() to start_removing()"
authorMiklos Szeredi <mszeredi@redhat.com>
Wed, 10 Jun 2026 10:57:21 +0000 (12:57 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Mon, 15 Jun 2026 12:06:15 +0000 (14:06 +0200)
This reverts commit cab012375122304a6343c1ed09404e5143b9dc01.

Commit c9ba789dad15 ("VFS: introduce start_creating_noperm() and
start_removing_noperm()") caused a regression in FUSE_NOTIFY_INVAL_ENTRY,
which failed to invalidate negative dentries.

This manifests in the filesystem returning -ENOENT for operations on an
existing file.

Fixing it properly while still keeping the start_removing* infrastructure
would add much additional complexity.

Instead revert to the original simple implementation.

The start_removing* infrastructure is needed in VFS to abstract the
filesystem locking.  However filesystem code can still safely use the raw
locking primitives without affacting other filesystems.

This is part one of the revert.

Reported-by: Артем Лабазов <123321artyom@gmail.com>
Closes: https://lore.kernel.org/all/CAFbF8N7++zopZuEcsKRxBV_sgOGCbzCY0hOyMw1SiGAtuzGhyQ@mail.gmail.com/
Fixes: c9ba789dad15 ("VFS: introduce start_creating_noperm() and start_removing_noperm()")
Cc: stable@vger.kernel.org # 6.19
Cc: NeilBrown <neilb@ownmail.net>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/fuse/dir.c

index b658b6baf72fe9149c2e79e33f8e4d6fd4b4b1cf..6b05846c9bed26a7a5c650af2ab9bafae2f963be 100644 (file)
@@ -1587,8 +1587,8 @@ int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid,
 {
        int err = -ENOTDIR;
        struct inode *parent;
-       struct dentry *dir = NULL;
-       struct dentry *entry = NULL;
+       struct dentry *dir;
+       struct dentry *entry;
 
        parent = fuse_ilookup(fc, parent_nodeid, NULL);
        if (!parent)
@@ -1601,19 +1601,11 @@ int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid,
        dir = d_find_alias(parent);
        if (!dir)
                goto put_parent;
-       while (!entry) {
-               struct dentry *child = try_lookup_noperm(name, dir);
-               if (!child || IS_ERR(child))
-                       goto put_parent;
-               entry = start_removing_dentry(dir, child);
-               dput(child);
-               if (IS_ERR(entry))
-                       goto put_parent;
-               if (!d_same_name(entry, dir, name)) {
-                       end_removing(entry);
-                       entry = NULL;
-               }
-       }
+
+       entry = start_removing_noperm(dir, name);
+       dput(dir);
+       if (IS_ERR(entry))
+               goto put_parent;
 
        fuse_dir_changed(parent);
        if (!(flags & FUSE_EXPIRE_ONLY))
@@ -1651,7 +1643,6 @@ int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid,
 
        end_removing(entry);
  put_parent:
-       dput(dir);
        iput(parent);
        return err;
 }