[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20251114092845.207368-1-lihongbo22@huawei.com>
Date: Fri, 14 Nov 2025 09:28:45 +0000
From: Hongbo Li <lihongbo22@...wei.com>
To: <hsiangkao@...ux.alibaba.com>, <chao@...nel.org>
CC: <linux-erofs@...ts.ozlabs.org>, <linux-kernel@...r.kernel.org>,
<lihongbo22@...wei.com>
Subject: [PATCH] erofs-utils: introduce --ishare_key option for local dir to support shared page cache
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=trusted.erofs.fingerprint foo.img foo/
Signed-off-by: Hongbo Li <lihongbo22@...wei.com>
---
include/erofs/config.h | 1 +
include/erofs/internal.h | 3 +++
include/erofs/xattr.h | 3 ++-
include/erofs_fs.h | 6 ++++--
lib/inode.c | 7 +++++++
lib/super.c | 2 ++
lib/xattr.c | 35 +++++++++++++++++++++++++++++++++--
mkfs/main.c | 26 +++++++++++++++++++++-----
8 files changed, 73 insertions(+), 10 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..482bee2 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -132,6 +132,8 @@ struct erofs_sb_info {
u8 xattr_prefix_count;
struct erofs_xattr_prefix_item *xattr_prefixes;
+ u8 ishare_key_start;
+
struct erofs_vfile bdev;
int devblksz;
u64 devsz;
@@ -186,6 +188,7 @@ EROFS_FEATURE_FUNCS(dedupe, incompat, INCOMPAT_DEDUPE)
EROFS_FEATURE_FUNCS(xattr_prefixes, incompat, INCOMPAT_XATTR_PREFIXES)
EROFS_FEATURE_FUNCS(48bit, incompat, INCOMPAT_48BIT)
EROFS_FEATURE_FUNCS(metabox, incompat, INCOMPAT_METABOX)
+EROFS_FEATURE_FUNCS(ishare_key, incompat, INCOMPAT_ISHARE_KEY)
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)
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;
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);
-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..1869844 100644
--- a/include/erofs_fs.h
+++ b/include/erofs_fs.h
@@ -34,8 +34,9 @@
#define EROFS_FEATURE_INCOMPAT_XATTR_PREFIXES 0x00000040
#define EROFS_FEATURE_INCOMPAT_48BIT 0x00000080
#define EROFS_FEATURE_INCOMPAT_METABOX 0x00000100
+#define EROFS_FEATURE_INCOMPAT_ISHARE_KEY 0x00000200
#define EROFS_ALL_FEATURE_INCOMPAT \
- ((EROFS_FEATURE_INCOMPAT_METABOX << 1) - 1)
+ ((EROFS_FEATURE_INCOMPAT_ISHARE_KEY << 1) - 1)
#define EROFS_SB_EXTSLOT_SIZE 16
@@ -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_key_start; /* 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_importer *im,
return ret;
}
+ if (!rebuild && cfg.ishare_key &&
+ S_ISREG(inode->i_mode) && inode->i_size) {
+ ret = erofs_hook_ishare_xattrs(inode, cfg.ishare_key);
+ if (ret < 0)
+ return ret;
+ }
+
if (!rebuild && !params->no_xattrs) {
ret = erofs_scan_file_xattrs(inode);
if (ret < 0)
diff --git a/lib/super.c b/lib/super.c
index d626c7c..f9ce1b7 100644
--- a/lib/super.c
+++ b/lib/super.c
@@ -137,6 +137,7 @@ int erofs_read_superblock(struct erofs_sb_info *sbi)
sbi->inos = le64_to_cpu(dsb->inos);
sbi->checksum = le32_to_cpu(dsb->checksum);
+ sbi->ishare_key_start = dsb->ishare_key_start;
sbi->epoch = (s64)le64_to_cpu(dsb->epoch);
sbi->fixed_nsec = le32_to_cpu(dsb->fixed_nsec);
sbi->build_time = le32_to_cpu(dsb->build_time);
@@ -196,6 +197,7 @@ int erofs_writesb(struct erofs_sb_info *sbi)
.xattr_blkaddr = cpu_to_le32(sbi->xattr_blkaddr),
.xattr_prefix_count = sbi->xattr_prefix_count,
.xattr_prefix_start = cpu_to_le32(sbi->xattr_prefix_start),
+ .ishare_key_start = sbi->ishare_key_start,
.feature_incompat = cpu_to_le32(sbi->feature_incompat),
.feature_compat = cpu_to_le32(sbi->feature_compat &
~EROFS_FEATURE_COMPAT_SB_CHKSUM),
diff --git a/lib/xattr.c b/lib/xattr.c
index 8f0332b..1548f8e 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"
#ifndef XATTR_SYSTEM_PREFIX
#define XATTR_SYSTEM_PREFIX "system."
@@ -475,7 +476,7 @@ err:
return ret;
}
-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 = inode->sbi;
@@ -573,6 +574,36 @@ static int erofs_droid_xattr_set_caps(struct erofs_inode *inode)
}
#endif
+int erofs_hook_ishare_xattrs(struct erofs_inode *inode, const char *ishare_key)
+{
+ erofs_off_t isize = inode->i_size;
+ void *buffer;
+ u8 sha256[32];
+ int ret, fd;
+
+ buffer = malloc(isize);
+ if (!buffer)
+ return -ENOMEM;
+
+ fd = open(inode->i_srcpath, O_RDONLY | O_BINARY);
+ if (fd < 0) {
+ ret = -errno;
+ goto free_err;
+ }
+ ret = erofs_io_pread(&(struct erofs_vfile){ .fd = fd }, buffer, isize, 0);
+ if (ret != isize) {
+ ret = -errno;
+ goto close_err;
+ }
+ erofs_sha256(buffer, isize, sha256);
+ ret = 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;
}
void erofs_xattr_cleanup_name_prefixes(void)
diff --git a/mkfs/main.c b/mkfs/main.c
index 76bf843..66507c3 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -102,6 +102,7 @@ static struct option long_options[] = {
#endif
{"zD", optional_argument, NULL, 536},
{"ZI", optional_argument, NULL, 537},
+ {"ishare_key", required_argument, NULL, 538},
{0, 0, 0, 0},
};
@@ -1261,7 +1262,7 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
case 19:
errno = 0;
opt = 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_importer_params *params,
else
mkfscfg.inode_metazone = false;
break;
+ case 538:
+ opt = 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 = optarg;
+ g_sbi.ishare_key_start = opt;
+ cfg.c_extra_ea_name_prefixes = 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;
}
- if (cfg.c_extra_ea_name_prefixes)
- erofs_xattr_flush_name_prefixes(&importer,
- mkfs_plain_xattr_pfx);
-
root = erofs_new_inode(&g_sbi);
if (IS_ERR(root)) {
err = PTR_ERR(root);
@@ -1965,6 +1974,13 @@ int main(int argc, char **argv)
goto exit;
}
+ if (cfg.c_extra_ea_name_prefixes) {
+ err = erofs_xattr_flush_name_prefixes(&importer,
+ mkfs_plain_xattr_pfx);
+ if (err)
+ goto exit;
+ }
+
err = erofs_importer_flush_all(&importer);
if (err)
goto exit;
--
2.22.0
Powered by blists - more mailing lists