2023-07-11 05:13:11

by Jiachen Zhang

[permalink] [raw]
Subject: [PATCH 0/5] FUSE consistency improvements

This patchset resends some patches that related to FUSE consistency
improvements in the mailing list.

The 1st patch fixes a staleness-checking issue, which is the v2 version
of the patch[1].

The 2nd patch is a resend version of the patch[2] with its commit message
rewritten.

The 3rd and 4th patches are new versions of the patch[3] and the patch[4],
FUSE filesystems are able to implement the close-to-open (CTO) consistency
semantics with the help of these two patches. The 5th patch is a new
patch which improves the explanation of FUSE cache mode and consistency
models in the documentation.


[1] [PATCH] fuse: initialize attr_version of new fuse inodes by fc->attr_version,
https://lore.kernel.org/lkml/[email protected]/
[2] [PATCH] fuse: invalidate dentry on EEXIST creates or ENOENT deletes,
https://lore.kernel.org/lkml/[email protected]/
[3] [PATCH] fuse: add FOPEN_INVAL_ATTR,
https://lore.kernel.org/lkml/[email protected]/
[4] [PATCH] fuse: writeback_cache consistency enhancement (writeback_cache_v2),
https://lore.kernel.org/lkml/[email protected]/


Jiachen Zhang (5):
fuse: check attributes staleness on fuse_iget()
fuse: invalidate dentry on EEXIST creates or ENOENT deletes
fuse: add FOPEN_INVAL_ATTR
fuse: writeback_cache consistency enhancement (writeback_cache_v2)
docs: fuse: improve FUSE consistency explanation

Documentation/filesystems/fuse-io.rst | 32 +++++++++++++++--
fs/fuse/dir.c | 11 +++---
fs/fuse/file.c | 35 +++++++++++++++++++
fs/fuse/fuse_i.h | 6 ++++
fs/fuse/inode.c | 49 +++++++++++++++++++++++++--
include/uapi/linux/fuse.h | 11 +++++-
6 files changed, 135 insertions(+), 9 deletions(-)

--
2.20.1



2023-07-11 05:18:22

by Jiachen Zhang

[permalink] [raw]
Subject: [PATCH 2/5] fuse: invalidate dentry on EEXIST creates or ENOENT deletes

The EEXIST errors returned from server are strong sign that a local
negative dentry should be invalidated. Similarly, The ENOENT errors from
server can also be a sign of revalidate failure. This commit invalidates
dentries on EEXIST creates and ENOENT deletes by calling
fuse_invalidate_entry(), which improves the consistency with no
performance degradation.

Signed-off-by: Jiachen Zhang <[email protected]>
---
fs/fuse/dir.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 5a4a7155cf1c..cfe38ee91ffd 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -755,7 +755,8 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
if (err == -ENOSYS) {
fc->no_create = 1;
goto mknod;
- }
+ } else if (err == -EEXIST)
+ fuse_invalidate_entry(entry);
out_dput:
dput(res);
return err;
@@ -835,6 +836,8 @@ static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args,
return 0;

out_put_forget_req:
+ if (err == -EEXIST)
+ fuse_invalidate_entry(entry);
kfree(forget);
return err;
}
@@ -986,7 +989,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
if (!err) {
fuse_dir_changed(dir);
fuse_entry_unlinked(entry);
- } else if (err == -EINTR)
+ } else if (err == -EINTR || err == -ENOENT)
fuse_invalidate_entry(entry);
return err;
}
@@ -1009,7 +1012,7 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
if (!err) {
fuse_dir_changed(dir);
fuse_entry_unlinked(entry);
- } else if (err == -EINTR)
+ } else if (err == -EINTR || err == -ENOENT)
fuse_invalidate_entry(entry);
return err;
}
@@ -1050,7 +1053,7 @@ static int fuse_rename_common(struct inode *olddir, struct dentry *oldent,
/* newent will end up negative */
if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent))
fuse_entry_unlinked(newent);
- } else if (err == -EINTR) {
+ } else if (err == -EINTR || err == -ENOENT) {
/* If request was interrupted, DEITY only knows if the
rename actually took place. If the invalidation
fails (e.g. some process has CWD under the renamed
--
2.20.1


2023-07-11 05:23:45

by Jiachen Zhang

[permalink] [raw]
Subject: [PATCH 3/5] fuse: add FOPEN_INVAL_ATTR

Add FOPEN_INVAL_ATTR so that the fuse daemon can ask kernel to invalidate
the attr cache on file open.

The fi->attr_version should be increased when handling FOPEN_INVAL_ATTR.
Because if a FUSE request returning attributes (getattr, setattr, lookup,
and readdirplus) starts before a FUSE_OPEN replying FOPEN_INVAL_ATTR, but
finishes after the FUSE_OPEN, staled attributes will be set to the inode
and falsely clears the inval_mask.

Signed-off-by: Jiachen Zhang <[email protected]>
---
fs/fuse/file.c | 10 ++++++++++
include/uapi/linux/fuse.h | 2 ++
2 files changed, 12 insertions(+)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index de37a3a06a71..412824a11b7b 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -215,6 +215,16 @@ void fuse_finish_open(struct inode *inode, struct file *file)
file_update_time(file);
fuse_invalidate_attr_mask(inode, FUSE_STATX_MODSIZE);
}
+
+ if (ff->open_flags & FOPEN_INVAL_ATTR) {
+ struct fuse_inode *fi = get_fuse_inode(inode);
+
+ spin_lock(&fi->lock);
+ fi->attr_version = atomic64_inc_return(&fc->attr_version);
+ fuse_invalidate_attr(inode);
+ spin_unlock(&fi->lock);
+ }
+
if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache)
fuse_link_write_file(file);
}
diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h
index b3fcab13fcd3..1a24c11637a4 100644
--- a/include/uapi/linux/fuse.h
+++ b/include/uapi/linux/fuse.h
@@ -315,6 +315,7 @@ struct fuse_file_lock {
* FOPEN_STREAM: the file is stream-like (no file position at all)
* FOPEN_NOFLUSH: don't flush data cache on close (unless FUSE_WRITEBACK_CACHE)
* FOPEN_PARALLEL_DIRECT_WRITES: Allow concurrent direct writes on the same inode
+ * FOPEN_INVAL_ATTR: invalidate the attr cache on open
*/
#define FOPEN_DIRECT_IO (1 << 0)
#define FOPEN_KEEP_CACHE (1 << 1)
@@ -323,6 +324,7 @@ struct fuse_file_lock {
#define FOPEN_STREAM (1 << 4)
#define FOPEN_NOFLUSH (1 << 5)
#define FOPEN_PARALLEL_DIRECT_WRITES (1 << 6)
+#define FOPEN_INVAL_ATTR (1 << 7)

/**
* INIT request/reply flags
--
2.20.1


2023-07-14 05:59:21

by Jingbo Xu

[permalink] [raw]
Subject: Re: [PATCH 0/5] FUSE consistency improvements



On 7/11/23 12:34 PM, Jiachen Zhang wrote:
> This patchset resends some patches that related to FUSE consistency
> improvements in the mailing list.
>
> The 1st patch fixes a staleness-checking issue, which is the v2 version
> of the patch[1].
>
> The 2nd patch is a resend version of the patch[2] with its commit message
> rewritten.
>
> The 3rd and 4th patches are new versions of the patch[3] and the patch[4],
> FUSE filesystems are able to implement the close-to-open (CTO) consistency
> semantics with the help of these two patches. The 5th patch is a new
> patch which improves the explanation of FUSE cache mode and consistency
> models in the documentation.
>

Yeah our internal production environment will also benefit from this
cache consistency enhancement. It would be great if this feature could
be improved and finally gets merged.


--
Thanks,
Jingbo