[PATCH] erofs: mark inodes without acls in erofs_read_inode()
Hongbo Li
lihongbo22 at huawei.com
Wed Jan 28 18:03:07 AEDT 2026
Hi, Xiang
On 2026/1/28 11:54, Gao Xiang wrote:
> 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.
>
> Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
> ---
> fs/erofs/inode.c | 5 +++++
> fs/erofs/xattr.c | 20 ++++++++++++++++++++
> fs/erofs/xattr.h | 1 +
> 3 files changed, 26 insertions(+)
>
> diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c
> index bce98c845a18..2e02d4b466ce 100644
> --- a/fs/erofs/inode.c
> +++ b/fs/erofs/inode.c
> @@ -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;
> diff --git a/fs/erofs/xattr.c b/fs/erofs/xattr.c
> index 512b998bdfff..14d22adc1476 100644
> --- a/fs/erofs/xattr.c
> +++ b/fs/erofs/xattr.c
> @@ -574,4 +574,24 @@ 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)
> +{
How about put the definition and declare of erofs_inode_has_noacl before
the erofs_get_acl helper? Since it is no need to resolved the context
conflicts for page sharing.
Otherwise it looks good to me:
Reviewed-by: Hongbo Li <lihongbo22 at huawei.com>
Thanks,
Hongbo
> + 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 ((ih->h_name_filter & bitmask) == bitmask)
> + return true;
> + }
> + return false;
> +}
> #endif
> diff --git a/fs/erofs/xattr.h b/fs/erofs/xattr.h
> index 36f2667afc2d..a3ceefa1554d 100644
> --- a/fs/erofs/xattr.h
> +++ b/fs/erofs/xattr.h
> @@ -30,4 +30,5 @@ struct posix_acl *erofs_get_acl(struct inode *inode, int type, bool rcu);
> #define erofs_get_acl (NULL)
> #endif
>
> +bool erofs_inode_has_noacl(struct inode *inode, void *kaddr, unsigned int ofs);
> #endif
More information about the Linux-erofs
mailing list