[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <176169811699.1426244.11280100587640231801.stgit@frogsfrogsfrogs>
Date: Tue, 28 Oct 2025 17:55:07 -0700
From: "Darrick J. Wong" <djwong@...nel.org>
To: djwong@...nel.org, miklos@...redi.hu
Cc: joannelkoong@...il.com, bernd@...ernd.com, neal@...pa.dev,
linux-ext4@...r.kernel.org, linux-fsdevel@...r.kernel.org
Subject: [PATCH 5/9] fuse: cache atime when in iomap mode
From: Darrick J. Wong <djwong@...nel.org>
When we're running in iomap mode, allow the kernel to cache the access
timestamp to further reduce the number of roundtrips to the fuse server.
Signed-off-by: "Darrick J. Wong" <djwong@...nel.org>
---
fs/fuse/dir.c | 5 +++++
fs/fuse/inode.c | 19 ++++++++++++++++---
2 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 492222862ed2b0..135c601230e547 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -2026,6 +2026,11 @@ int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
inarg.ctime = inode_get_ctime_sec(inode);
inarg.ctimensec = inode_get_ctime_nsec(inode);
}
+ if (fuse_inode_has_iomap(inode)) {
+ inarg.valid |= FATTR_ATIME;
+ inarg.atime = inode_get_atime_sec(inode);
+ inarg.atimensec = inode_get_atime_nsec(inode);
+ }
if (ff) {
inarg.valid |= FATTR_FH;
inarg.fh = ff->fh;
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 707bd3718be681..c82c6a29904396 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -263,7 +263,8 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr,
attr->mtimensec = min_t(u32, attr->mtimensec, NSEC_PER_SEC - 1);
attr->ctimensec = min_t(u32, attr->ctimensec, NSEC_PER_SEC - 1);
- inode_set_atime(inode, attr->atime, attr->atimensec);
+ if (!(cache_mask & STATX_ATIME))
+ inode_set_atime(inode, attr->atime, attr->atimensec);
/* mtime from server may be stale due to local buffered write */
if (!(cache_mask & STATX_MTIME)) {
inode_set_mtime(inode, attr->mtime, attr->mtimensec);
@@ -326,8 +327,12 @@ u32 fuse_get_cache_mask(struct inode *inode)
{
struct fuse_conn *fc = get_fuse_conn(inode);
- if (S_ISREG(inode->i_mode) &&
- (fuse_inode_has_iomap(inode) || fc->writeback_cache))
+ if (!S_ISREG(inode->i_mode))
+ return 0;
+
+ if (fuse_inode_has_iomap(inode))
+ return STATX_MTIME | STATX_CTIME | STATX_ATIME | STATX_SIZE;
+ if (fc->writeback_cache)
return STATX_MTIME | STATX_CTIME | STATX_SIZE;
return 0;
@@ -458,6 +463,14 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr,
BUG();
break;
}
+
+ /*
+ * iomap caches atime too, so we must load it from the fuse server
+ * at instantiation time.
+ */
+ if (fuse_inode_has_iomap(inode))
+ inode_set_atime(inode, attr->atime, attr->atimensec);
+
/*
* Ensure that we don't cache acls for daemons without FUSE_POSIX_ACL
* so they see the exact same behavior as before.
Powered by blists - more mailing lists