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;
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
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