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


Reply via email to