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 <[email protected]> --- 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 { u32 xattr_prefix_start; u8 xattr_prefix_count; + u8 ishare_xattr_pfx; struct erofs_xattr_prefix_item *xattr_prefixes; 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) #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; 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..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 /* * 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_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..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 = le64_to_cpu(dsb->inos); sbi->checksum = le32_to_cpu(dsb->checksum); + if (erofs_sb_has_ishare_key(sbi)) + sbi->ishare_xattr_pfx = + dsb->ishare_xattr_prefix_id & EROFS_XATTR_LONG_PREFIX_MASK; 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 +199,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_xattr_prefix_id = sbi->ishare_xattr_pfx, .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..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" #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) @@ -1718,6 +1749,19 @@ int erofs_xattr_prefixes_init(struct erofs_sb_info *sbi) pfs[i].infix_len = len - sizeof(struct erofs_xattr_long_prefix); } out: + if (!ret && erofs_sb_has_ishare_key(sbi)) { + struct erofs_xattr_prefix_item *pf = pfs + sbi->ishare_xattr_pfx; + struct erofs_xattr_long_prefix *newpfx; + + newpfx = realloc(pf->prefix, + sizeof(*newpfx) + pf->infix_len + 1); + if (newpfx) { + newpfx->infix[pf->infix_len] = '\0'; + pf->prefix = newpfx; + } else { + ret = -ENOMEM; + } + } sbi->xattr_prefixes = 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[] = { #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_xattr_pfx = 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
