]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
erofs: mark inodes without acls in erofs_read_inode()
authorGao Xiang <hsiangkao@linux.alibaba.com>
Wed, 28 Jan 2026 03:54:08 +0000 (11:54 +0800)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Wed, 28 Jan 2026 07:38:37 +0000 (15:38 +0800)
Similar to commit 91ef18b567da ("ext4: mark inodes without acls in
__ext4_iget()"), the ACL state won't be read when the file owner
performs a lookup, and the RCU fast path for lookups won't work
because the ACL state remains unknown.

If there are no extended attributes, or if the xattr filter
indicates that no ACL xattr is present, call cache_no_acl() directly.

Reviewed-by: Hongbo Li <lihongbo22@huawei.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
fs/erofs/inode.c
fs/erofs/xattr.c
fs/erofs/xattr.h

index d33816cff813972a8c28bb1966cadec74de7c714..2ecc28abd6cd0418fa6141d431b7d74b9a56aa91 100644 (file)
@@ -137,6 +137,11 @@ static int erofs_read_inode(struct inode *inode)
                err = -EFSCORRUPTED;
                goto err_out;
        }
+
+       if (IS_ENABLED(CONFIG_EROFS_FS_POSIX_ACL) &&
+           erofs_inode_has_noacl(inode, ptr, ofs))
+               cache_no_acl(inode);
+
        switch (inode->i_mode & S_IFMT) {
        case S_IFDIR:
                vi->dot_omitted = (ifmt >> EROFS_I_DOT_OMITTED_BIT) & 1;
index 2ef9d6436b05ee51d0bfe3487b4d83674cbbdf8e..b7da1ed83160b8891c4dd9020d8befdd4b849014 100644 (file)
@@ -587,6 +587,26 @@ struct posix_acl *erofs_get_acl(struct inode *inode, int type, bool rcu)
        kfree(value);
        return acl;
 }
+
+bool erofs_inode_has_noacl(struct inode *inode, void *kaddr, unsigned int ofs)
+{
+       static const unsigned int bitmask =
+               BIT(21) |       /* system.posix_acl_default */
+               BIT(30);        /* system.posix_acl_access */
+       struct erofs_sb_info *sbi = EROFS_I_SB(inode);
+       const struct erofs_xattr_ibody_header *ih = kaddr + ofs;
+
+       if (EROFS_I(inode)->xattr_isize < sizeof(*ih))
+               return true;
+
+       if (erofs_sb_has_xattr_filter(sbi) && !sbi->xattr_filter_reserved &&
+           !check_add_overflow(ofs, sizeof(*ih), &ofs) &&
+           ofs <= i_blocksize(inode)) {
+               if ((le32_to_cpu(ih->h_name_filter) & bitmask) == bitmask)
+                       return true;
+       }
+       return false;
+}
 #endif
 
 #ifdef CONFIG_EROFS_FS_PAGE_CACHE_SHARE
index 4d0e58ff7a1404f0d44a83787ca7168082d35bf2..4465f7018a417b655e1a4c95a54397a6484cb90e 100644 (file)
@@ -32,5 +32,5 @@ struct posix_acl *erofs_get_acl(struct inode *inode, int type, bool rcu);
 
 int erofs_xattr_fill_inode_fingerprint(struct erofs_inode_fingerprint *fp,
                                       struct inode *inode, const char *domain_id);
-
+bool erofs_inode_has_noacl(struct inode *inode, void *kaddr, unsigned int ofs);
 #endif