Commit 1729f7c6 authored by Gao Xiang's avatar Gao Xiang
Browse files

erofs: mark inodes without acls in erofs_read_inode()



Similar to commit 91ef18b5 ("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: default avatarHongbo Li <lihongbo22@huawei.com>
Signed-off-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
parent d86d7817
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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;
+20 −0
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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