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 <zhangjiachen.jaycee@xxxxxxxxxxxxx> --- 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