On 1/23/24 09:40, Yuan Yao wrote:
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,
Thank you and sorry for my late reply! Yeah definitely makes sense, I'm
just going add it in and will also add a small comment. And as I said, I
first need to address all the issues Al had found - still didn't have
time for it.
Thanks,
Bernd