[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <176169811785.1426244.13970477450791549525.stgit@frogsfrogsfrogs>
Date: Tue, 28 Oct 2025 17:56:10 -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 9/9] fuse: always cache ACLs when using iomap
From: Darrick J. Wong <djwong@...nel.org>
Keep ACLs cached in memory when we're using iomap, so that we don't have
to make a round trip to the fuse server. This might want to become a
FUSE_ATTR_ flag.
Signed-off-by: "Darrick J. Wong" <djwong@...nel.org>
---
fs/fuse/acl.c | 12 +++++++++---
fs/fuse/dir.c | 11 ++++++++---
fs/fuse/readdir.c | 3 ++-
3 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/fs/fuse/acl.c b/fs/fuse/acl.c
index bdd209b9908c2d..633a73be710b2f 100644
--- a/fs/fuse/acl.c
+++ b/fs/fuse/acl.c
@@ -213,10 +213,16 @@ int fuse_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
if (fc->posix_acl) {
/*
* Fuse daemons without FUSE_POSIX_ACL never cached POSIX ACLs
- * and didn't invalidate attributes. Retain that behavior.
+ * and didn't invalidate attributes. Retain that behavior
+ * except for iomap, where we assume that only the source of
+ * ACL changes is userspace.
*/
- forget_all_cached_acls(inode);
- fuse_invalidate_attr(inode);
+ if (!ret && is_iomap) {
+ set_cached_acl(inode, type, acl);
+ } else {
+ forget_all_cached_acls(inode);
+ fuse_invalidate_attr(inode);
+ }
}
return ret;
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 4fc66ff0231089..55a46612e3677c 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -261,7 +261,8 @@ static int fuse_dentry_revalidate(struct inode *dir, const struct qstr *name,
fuse_stale_inode(inode, outarg.generation, &outarg.attr))
goto invalid;
- forget_all_cached_acls(inode);
+ if (!fuse_inode_has_iomap(inode))
+ forget_all_cached_acls(inode);
fuse_change_attributes(inode, &outarg.attr, NULL,
ATTR_TIMEOUT(&outarg),
attr_version);
@@ -1463,7 +1464,8 @@ static int fuse_update_get_attr(struct mnt_idmap *idmap, struct inode *inode,
sync = time_before64(fi->i_time, get_jiffies_64());
if (sync) {
- forget_all_cached_acls(inode);
+ if (!fuse_inode_has_iomap(inode))
+ forget_all_cached_acls(inode);
/* Try statx if a field not covered by regular stat is wanted */
if (!fc->no_statx && (request_mask & ~STATX_BASIC_STATS)) {
err = fuse_do_statx(idmap, inode, file, stat);
@@ -1641,6 +1643,9 @@ static int fuse_access(struct inode *inode, int mask)
static int fuse_perm_getattr(struct inode *inode, int mask)
{
+ if (fuse_inode_has_iomap(inode))
+ return 0;
+
if (mask & MAY_NOT_BLOCK)
return -ECHILD;
@@ -2318,7 +2323,7 @@ static int fuse_setattr(struct mnt_idmap *idmap, struct dentry *entry,
* If filesystem supports acls it may have updated acl xattrs in
* the filesystem, so forget cached acls for the inode.
*/
- if (fc->posix_acl)
+ if (fc->posix_acl && !is_iomap)
forget_all_cached_acls(inode);
/* Directory mode changed, may need to revalidate access */
diff --git a/fs/fuse/readdir.c b/fs/fuse/readdir.c
index 45dd932eb03a5e..f7c2a45f23678e 100644
--- a/fs/fuse/readdir.c
+++ b/fs/fuse/readdir.c
@@ -224,7 +224,8 @@ static int fuse_direntplus_link(struct file *file,
fi->nlookup++;
spin_unlock(&fi->lock);
- forget_all_cached_acls(inode);
+ if (!fuse_inode_has_iomap(inode))
+ forget_all_cached_acls(inode);
fuse_change_attributes(inode, &o->attr, NULL,
ATTR_TIMEOUT(o),
attr_version);
Powered by blists - more mailing lists