From nobody Tue Dec 2 02:43:28 2025 Received: from canpmsgout12.his.huawei.com (canpmsgout12.his.huawei.com [113.46.200.227]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DFD782F6909 for ; Tue, 18 Nov 2025 02:10:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.227 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763431837; cv=none; b=MoZiFXr2CZgDPKZI1NSlgQxL3PPBXcY0yYLK+bOs3IuWoCZTprCdj5/gyw3OJAtDS75t30GyhDJvk9asV4dAcjADOU5kCmu1XPg02X8qsWAtuLG4NQBBpNtYfh64LPOrkvxwUaRvVdhPwMfY9MsUVv9n6Lh3wzpxYwiS3mN3t40= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763431837; c=relaxed/simple; bh=a03QGGBKHGD4vVlIAWsmCkyvnyMVC381sZmYcz6xe/E=; h=From:To:CC:Subject:Date:Message-ID:MIME-Version:Content-Type; b=YWVrNIA0+2xgh7vgWqRHJziezaj6Rukc+euzz0qWssNJX63XBinYwkcIyX0lDTlMICrQ16jbYPJATWgSMzZrLMXhqzLYJs5TbSplTZ5sjSgPqWJOA2de4aSqNqCuA8sSeC5kyes72HKsEY8HgGQVbwoan+oq7/jgyA4mPF4Ik+E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=F9DVcDiH; arc=none smtp.client-ip=113.46.200.227 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="F9DVcDiH" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=maCpeDUW32MuzuP5dydiseQ/n1MjVteCpkL15HmNg4Y=; b=F9DVcDiHifC7pnovs8OZ2wADq+Ij6Ae9899sctBmhwchG8ZmXqc4R7SrUrd1LesdKaM23r4m7 qtFh1UAhLPhDxhjz9upDioTI8d+9131r3vAzjZdPsUZ4ZSFkL6bPLNxaP+kA+XPI8Pkhuxo5dJU BHJ0VktMsJ50vvzHbwUBFLE= Received: from mail.maildlp.com (unknown [172.19.162.112]) by canpmsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4d9Shm1lRmznTW4; Tue, 18 Nov 2025 10:08:56 +0800 (CST) Received: from kwepemr500015.china.huawei.com (unknown [7.202.195.162]) by mail.maildlp.com (Postfix) with ESMTPS id 756D31401F1; Tue, 18 Nov 2025 10:10:24 +0800 (CST) Received: from huawei.com (10.67.174.162) by kwepemr500015.china.huawei.com (7.202.195.162) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Tue, 18 Nov 2025 10:10:23 +0800 From: Hongbo Li To: , CC: , , Subject: [PATCH v2] erofs-utils: introduce --ishare_key option for local dir to support shared page cache Date: Tue, 18 Nov 2025 01:58:49 +0000 Message-ID: <20251118015849.228939-1-lihongbo22@huawei.com> X-Mailer: git-send-email 2.22.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems200002.china.huawei.com (7.221.188.68) To kwepemr500015.china.huawei.com (7.202.195.162) Content-Type: text/plain; charset="utf-8" For uncoming page cache sharing feature, we provide the --ishare_key option to calculate the sha256 on content for localdir. The usage is like: mkfs.erofs --ishare_key=3Dtrusted.erofs.fingerprint foo.img foo/ Signed-off-by: Hongbo Li --- include/erofs/config.h | 1 + include/erofs/internal.h | 2 ++ include/erofs/xattr.h | 3 ++- include/erofs_fs.h | 4 +++- lib/inode.c | 7 ++++++ lib/super.c | 4 ++++ lib/xattr.c | 48 ++++++++++++++++++++++++++++++++++++++-- mkfs/main.c | 26 +++++++++++++++++----- 8 files changed, 86 insertions(+), 9 deletions(-) diff --git a/include/erofs/config.h b/include/erofs/config.h index 525a8cd..dd4fa73 100644 --- a/include/erofs/config.h +++ b/include/erofs/config.h @@ -61,6 +61,7 @@ struct erofs_configure { u64 c_unix_timestamp; const char *mount_point; u32 c_root_xattr_isize; + const char *ishare_key; #ifdef EROFS_MT_ENABLED u64 c_mkfs_segment_size; u32 c_mt_workers; diff --git a/include/erofs/internal.h b/include/erofs/internal.h index 62594b8..6d1b7b9 100644 --- a/include/erofs/internal.h +++ b/include/erofs/internal.h @@ -130,6 +130,7 @@ struct erofs_sb_info { =20 u32 xattr_prefix_start; u8 xattr_prefix_count; + u8 ishare_xattr_pfx; struct erofs_xattr_prefix_item *xattr_prefixes; =20 struct erofs_vfile bdev; @@ -189,6 +190,7 @@ EROFS_FEATURE_FUNCS(metabox, incompat, INCOMPAT_METABOX) EROFS_FEATURE_FUNCS(sb_chksum, compat, COMPAT_SB_CHKSUM) EROFS_FEATURE_FUNCS(xattr_filter, compat, COMPAT_XATTR_FILTER) EROFS_FEATURE_FUNCS(plain_xattr_pfx, compat, COMPAT_PLAIN_XATTR_PFX) +EROFS_FEATURE_FUNCS(ishare_key, compat, COMPAT_ISHARE_KEY) =20 #define EROFS_I_EA_INITED_BIT 0 #define EROFS_I_Z_INITED_BIT 1 diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h index ef80123..c1a4205 100644 --- a/include/erofs/xattr.h +++ b/include/erofs/xattr.h @@ -46,6 +46,7 @@ static inline unsigned int xattrblock_offset(struct erofs= _inode *vi, struct erofs_importer; =20 int erofs_xattr_init(struct erofs_sb_info *sbi); +int erofs_hook_ishare_xattrs(struct erofs_inode *inode, const char *ishare= _key); int erofs_scan_file_xattrs(struct erofs_inode *inode); int erofs_prepare_xattr_ibody(struct erofs_inode *inode, bool noroom); char *erofs_export_xattr_ibody(struct erofs_inode *inode); @@ -56,7 +57,7 @@ void erofs_xattr_cleanup_name_prefixes(void); int erofs_xattr_flush_name_prefixes(struct erofs_importer *im, bool plain); int erofs_xattr_prefixes_init(struct erofs_sb_info *sbi); =20 -int erofs_setxattr(struct erofs_inode *inode, char *key, +int erofs_setxattr(struct erofs_inode *inode, const char *key, const void *value, size_t size); int erofs_set_opaque_xattr(struct erofs_inode *inode); void erofs_clear_opaque_xattr(struct erofs_inode *inode); diff --git a/include/erofs_fs.h b/include/erofs_fs.h index 887f37f..a379752 100644 --- a/include/erofs_fs.h +++ b/include/erofs_fs.h @@ -17,6 +17,7 @@ #define EROFS_FEATURE_COMPAT_MTIME 0x00000002 #define EROFS_FEATURE_COMPAT_XATTR_FILTER 0x00000004 #define EROFS_FEATURE_COMPAT_PLAIN_XATTR_PFX 0x00000010 +#define EROFS_FEATURE_COMPAT_ISHARE_KEY 0x00000020 =20 /* * Any bits that aren't in EROFS_ALL_FEATURE_INCOMPAT should @@ -82,7 +83,8 @@ struct erofs_super_block { __le32 xattr_prefix_start; /* start of long xattr prefixes */ __le64 packed_nid; /* nid of the special packed inode */ __u8 xattr_filter_reserved; /* reserved for xattr name filter */ - __u8 reserved[3]; + __u8 ishare_xattr_prefix_id; /* start of ishare key */ + __u8 reserved[2]; __le32 build_time; /* seconds added to epoch for mkfs time */ __le64 rootnid_8b; /* (48BIT on) nid of root directory */ __le64 reserved2; diff --git a/lib/inode.c b/lib/inode.c index d993c8f..92ecce7 100644 --- a/lib/inode.c +++ b/lib/inode.c @@ -1899,6 +1899,13 @@ static int erofs_mkfs_handle_inode(struct erofs_impo= rter *im, return ret; } =20 + if (!rebuild && cfg.ishare_key && + S_ISREG(inode->i_mode) && inode->i_size) { + ret =3D erofs_hook_ishare_xattrs(inode, cfg.ishare_key); + if (ret < 0) + return ret; + } + if (!rebuild && !params->no_xattrs) { ret =3D erofs_scan_file_xattrs(inode); if (ret < 0) diff --git a/lib/super.c b/lib/super.c index d626c7c..7e41ef8 100644 --- a/lib/super.c +++ b/lib/super.c @@ -137,6 +137,9 @@ int erofs_read_superblock(struct erofs_sb_info *sbi) sbi->inos =3D le64_to_cpu(dsb->inos); sbi->checksum =3D le32_to_cpu(dsb->checksum); =20 + if (erofs_sb_has_ishare_key(sbi)) + sbi->ishare_xattr_pfx =3D + dsb->ishare_xattr_prefix_id & EROFS_XATTR_LONG_PREFIX_MASK; sbi->epoch =3D (s64)le64_to_cpu(dsb->epoch); sbi->fixed_nsec =3D le32_to_cpu(dsb->fixed_nsec); sbi->build_time =3D le32_to_cpu(dsb->build_time); @@ -196,6 +199,7 @@ int erofs_writesb(struct erofs_sb_info *sbi) .xattr_blkaddr =3D cpu_to_le32(sbi->xattr_blkaddr), .xattr_prefix_count =3D sbi->xattr_prefix_count, .xattr_prefix_start =3D cpu_to_le32(sbi->xattr_prefix_start), + .ishare_xattr_prefix_id =3D sbi->ishare_xattr_pfx, .feature_incompat =3D cpu_to_le32(sbi->feature_incompat), .feature_compat =3D cpu_to_le32(sbi->feature_compat & ~EROFS_FEATURE_COMPAT_SB_CHKSUM), diff --git a/lib/xattr.c b/lib/xattr.c index 8f0332b..d27e037 100644 --- a/lib/xattr.c +++ b/lib/xattr.c @@ -21,6 +21,7 @@ #include "liberofs_metabox.h" #include "liberofs_xxhash.h" #include "liberofs_private.h" +#include "sha256.h" =20 #ifndef XATTR_SYSTEM_PREFIX #define XATTR_SYSTEM_PREFIX "system." @@ -475,7 +476,7 @@ err: return ret; } =20 -int erofs_setxattr(struct erofs_inode *inode, char *key, +int erofs_setxattr(struct erofs_inode *inode, const char *key, const void *value, size_t size) { struct erofs_sb_info *sbi =3D inode->sbi; @@ -573,6 +574,36 @@ static int erofs_droid_xattr_set_caps(struct erofs_ino= de *inode) } #endif =20 +int erofs_hook_ishare_xattrs(struct erofs_inode *inode, const char *ishare= _key) +{ + erofs_off_t isize =3D inode->i_size; + void *buffer; + u8 sha256[32]; + int ret, fd; + + buffer =3D malloc(isize); + if (!buffer) + return -ENOMEM; + + fd =3D open(inode->i_srcpath, O_RDONLY | O_BINARY); + if (fd < 0) { + ret =3D -errno; + goto free_err; + } + ret =3D erofs_io_pread(&(struct erofs_vfile){ .fd =3D fd }, buffer, isize= , 0); + if (ret !=3D isize) { + ret =3D -errno; + goto close_err; + } + erofs_sha256(buffer, isize, sha256); + ret =3D erofs_setxattr(inode, ishare_key, sha256, 32); +close_err: + close(fd); +free_err: + free(buffer); + return ret; +} + int erofs_scan_file_xattrs(struct erofs_inode *inode) { int ret; @@ -1653,7 +1684,7 @@ int erofs_xattr_insert_name_prefix(const char *prefix) ea_prefix_count++; init_list_head(&tnode->list); list_add_tail(&tnode->list, &ea_name_prefixes); - return 0; + return tnode->index; } =20 void erofs_xattr_cleanup_name_prefixes(void) @@ -1718,6 +1749,19 @@ int erofs_xattr_prefixes_init(struct erofs_sb_info *= sbi) pfs[i].infix_len =3D len - sizeof(struct erofs_xattr_long_prefix); } out: + if (!ret && erofs_sb_has_ishare_key(sbi)) { + struct erofs_xattr_prefix_item *pf =3D pfs + sbi->ishare_xattr_pfx; + struct erofs_xattr_long_prefix *newpfx; + + newpfx =3D realloc(pf->prefix, + sizeof(*newpfx) + pf->infix_len + 1); + if (newpfx) { + newpfx->infix[pf->infix_len] =3D '\0'; + pf->prefix =3D newpfx; + } else { + ret =3D -ENOMEM; + } + } sbi->xattr_prefixes =3D pfs; if (ret) erofs_xattr_prefixes_cleanup(sbi); diff --git a/mkfs/main.c b/mkfs/main.c index 76bf843..5eb5bf8 100644 --- a/mkfs/main.c +++ b/mkfs/main.c @@ -102,6 +102,7 @@ static struct option long_options[] =3D { #endif {"zD", optional_argument, NULL, 536}, {"ZI", optional_argument, NULL, 537}, + {"ishare_key", required_argument, NULL, 538}, {0, 0, 0, 0}, }; =20 @@ -1261,7 +1262,7 @@ static int mkfs_parse_options_cfg(struct erofs_import= er_params *params, case 19: errno =3D 0; opt =3D erofs_xattr_insert_name_prefix(optarg); - if (opt) { + if (opt < 0) { erofs_err("failed to parse xattr name prefix: %s", erofs_strerror(opt)); return opt; @@ -1421,6 +1422,18 @@ static int mkfs_parse_options_cfg(struct erofs_impor= ter_params *params, else mkfscfg.inode_metazone =3D false; break; + case 538: + opt =3D erofs_xattr_insert_name_prefix(optarg); + if (opt < 0) { + erofs_err("failed to parse xattr name prefix: %s", + erofs_strerror(opt)); + return opt; + } + cfg.ishare_key =3D optarg; + g_sbi.ishare_xattr_pfx =3D opt; + cfg.c_extra_ea_name_prefixes =3D true; + erofs_sb_set_ishare_key(&g_sbi); + break; case 'V': version(); exit(0); @@ -1875,10 +1888,6 @@ int main(int argc, char **argv) goto exit; } =20 - if (cfg.c_extra_ea_name_prefixes) - erofs_xattr_flush_name_prefixes(&importer, - mkfs_plain_xattr_pfx); - root =3D erofs_new_inode(&g_sbi); if (IS_ERR(root)) { err =3D PTR_ERR(root); @@ -1965,6 +1974,13 @@ int main(int argc, char **argv) goto exit; } =20 + if (cfg.c_extra_ea_name_prefixes) { + err =3D erofs_xattr_flush_name_prefixes(&importer, + mkfs_plain_xattr_pfx); + if (err) + goto exit; + } + err =3D erofs_importer_flush_all(&importer); if (err) goto exit; --=20 2.22.0