mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
fuse: do not use start_removing_noperm()
Revert the fuse part of commitc9ba789dad("VFS: introduce start_creating_noperm() and start_removing_noperm()"). Commitc9ba789dad("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 two of the revert. Reported-by: Артем Лабазов <123321artyom@gmail.com> Closes: https://lore.kernel.org/all/CAFbF8N7++zopZuEcsKRxBV_sgOGCbzCY0hOyMw1SiGAtuzGhyQ@mail.gmail.com/ Fixes:c9ba789dad("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>
This commit is contained in:
parent
c12bbaf7c2
commit
6e1b235627
|
|
@ -1594,25 +1594,27 @@ int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid,
|
|||
if (!parent)
|
||||
return -ENOENT;
|
||||
|
||||
inode_lock_nested(parent, I_MUTEX_PARENT);
|
||||
if (!S_ISDIR(parent->i_mode))
|
||||
goto put_parent;
|
||||
goto unlock;
|
||||
|
||||
err = -ENOENT;
|
||||
dir = d_find_alias(parent);
|
||||
if (!dir)
|
||||
goto put_parent;
|
||||
goto unlock;
|
||||
|
||||
entry = start_removing_noperm(dir, name);
|
||||
name->hash = full_name_hash(dir, name->name, name->len);
|
||||
entry = d_lookup(dir, name);
|
||||
dput(dir);
|
||||
if (IS_ERR(entry))
|
||||
goto put_parent;
|
||||
if (!entry)
|
||||
goto unlock;
|
||||
|
||||
fuse_dir_changed(parent);
|
||||
if (!(flags & FUSE_EXPIRE_ONLY))
|
||||
d_invalidate(entry);
|
||||
fuse_invalidate_entry_cache(entry);
|
||||
|
||||
if (child_nodeid != 0) {
|
||||
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;
|
||||
|
|
@ -1640,9 +1642,10 @@ int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid,
|
|||
} else {
|
||||
err = 0;
|
||||
}
|
||||
dput(entry);
|
||||
|
||||
end_removing(entry);
|
||||
put_parent:
|
||||
unlock:
|
||||
inode_unlock(parent);
|
||||
iput(parent);
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user