With current implementation, when fuse server replies a negative d_entry, _fuse_atomic_open() function will return ENOENT error. This behaviour will prevent using kernel's negative d_entry. The original fuse_create_open() function will get negative d_entry by fuse_lookup(). And the finish_no_open() will be called with that negative d_entry. This patch fixes the problem by adding a check for the case that negative d_entry is returned by fuse server. Atomic open will update the d_entry's timeout and call finish_no_open(). This change makes negative d_entry be used in kernel. Signed-off-by: Yuan Yao <yuanyaogoog@xxxxxxxxxxxx> --- fs/fuse/dir.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 4ae89f428243..11b3193c3902 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -843,8 +843,15 @@ static int _fuse_atomic_open(struct inode *dir, struct dentry *entry, goto free_and_fallback; } - if (!err && !outentry.nodeid) + if (!err && !outentry.nodeid) { + if (outentry.entry_valid) { + inode = NULL; + d_splice_alias(inode, entry); + fuse_change_entry_timeout(entry, &outentry); + goto free_and_no_open; + } err = -ENOENT; + } if (err) goto out_free_ff; @@ -991,6 +998,10 @@ static int _fuse_atomic_open(struct inode *dir, struct dentry *entry, kfree(forget); fallback: return fuse_create_open(dir, entry, file, flags, mode); +free_and_no_open: + fuse_file_free(ff); + kfree(forget); + return finish_no_open(file, entry); } static int fuse_atomic_open(struct inode *dir, struct dentry *entry, -- 2.43.0.429.g432eaa2c6b-goog