since FUSE caches dentries and attributes with separate timeout, It may happen that checking the permission returns -ENOENT, but because the dentries cache has not timed out, creating the file returns -EEXIST. Fix this by when return ENOENT, mark the entry as stale. Signed-off-by: Fengnan Chang <changfengnan@xxxxxxxx> --- fs/fuse/dir.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 06a18700a845..154dd4578762 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -1065,6 +1065,14 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat, fuse_fillattr(inode, &outarg.attr, stat); } } + if (err == -ENOENT) { + struct dentry *entry; + + entry = d_obtain_alias(inode); + if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) + fuse_invalidate_entry_cache(entry); + } + return err; } @@ -1226,6 +1234,14 @@ static int fuse_access(struct inode *inode, int mask) fm->fc->no_access = 1; err = 0; } + if (err == -ENOENT) { + struct dentry *entry; + + entry = d_obtain_alias(inode); + if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) + fuse_invalidate_entry_cache(entry); + } + return err; } -- 2.29.0