From: Darrick J. Wong <djwong@xxxxxxxxxx> 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@xxxxxxxxxx> --- fs/fuse/acl.c | 8 ++++++-- fs/fuse/dir.c | 11 ++++++++--- fs/fuse/readdir.c | 3 ++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/fs/fuse/acl.c b/fs/fuse/acl.c index efab333415131c..404c96ad68ea66 100644 --- a/fs/fuse/acl.c +++ b/fs/fuse/acl.c @@ -201,8 +201,12 @@ int fuse_set_acl(struct mnt_idmap *idmap, struct dentry *dentry, * Fuse daemons without FUSE_POSIX_ACL never cached POSIX ACLs * and didn't invalidate attributes. Retain that behavior. */ - forget_all_cached_acls(inode); - fuse_invalidate_attr(inode); + if (!ret && fuse_has_iomap(inode)) { + 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 e8eef46d8e1b52..d317b7965a8259 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); @@ -1468,7 +1469,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); @@ -1645,6 +1647,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; @@ -2321,7 +2326,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 && !fuse_inode_has_iomap(inode)) 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);