erofs-utils: introduce z_erofs_parse_cfgs()
authorGao Xiang <hsiangkao@linux.alibaba.com>
Wed, 5 Jun 2024 12:14:47 +0000 (20:14 +0800)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Wed, 5 Jun 2024 13:22:46 +0000 (21:22 +0800)
This userspace implementation will be mainly used for the upcoming
Intel In-Memory Analytics Accelerator integration.

Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Link: https://lore.kernel.org/r/20240605121448.3816160-1-hsiangkao@linux.alibaba.com
include/erofs/internal.h
lib/decompress.c
lib/super.c

index 9fdff7101056bb073e4fb5ae25c1ecc0e3226350..d52bcc656521cbb1556268d366e28da34786d4a7 100644 (file)
@@ -410,6 +410,7 @@ int z_erofs_read_one_data(struct erofs_inode *inode,
                        erofs_off_t skip, erofs_off_t length, bool trimmed);
 void *erofs_read_metadata(struct erofs_sb_info *sbi, erofs_nid_t nid,
                          erofs_off_t *offset, int *lengthp);
+int z_erofs_parse_cfgs(struct erofs_sb_info *sbi, struct erofs_super_block *dsb);
 
 static inline int erofs_get_occupied_size(const struct erofs_inode *inode,
                                          erofs_off_t *size)
index e65b924193863cb18c8c6003199d1c563091b619..2842f51b595285ff036cf2286a8c8a2a6759aabb 100644 (file)
@@ -382,3 +382,44 @@ int z_erofs_decompress(struct z_erofs_decompress_req *rq)
 #endif
        return -EOPNOTSUPP;
 }
+
+int z_erofs_parse_cfgs(struct erofs_sb_info *sbi, struct erofs_super_block *dsb)
+{
+       unsigned int algs, alg;
+       erofs_off_t offset;
+       int size, ret = 0;
+
+       if (!erofs_sb_has_compr_cfgs(sbi)) {
+               sbi->available_compr_algs = 1 << Z_EROFS_COMPRESSION_LZ4;
+               sbi->lz4_max_distance = le16_to_cpu(dsb->u1.lz4_max_distance);
+               return 0;
+       }
+
+       sbi->available_compr_algs = le16_to_cpu(dsb->u1.available_compr_algs);
+       if (sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS) {
+               erofs_err("unidentified algorithms %x, please upgrade erofs-utils",
+                         sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS);
+               return -EOPNOTSUPP;
+       }
+
+       offset = EROFS_SUPER_OFFSET + sbi->sb_size;
+       alg = 0;
+       for (algs = sbi->available_compr_algs; algs; algs >>= 1, ++alg) {
+               void *data;
+
+               if (!(algs & 1))
+                       continue;
+
+               data = erofs_read_metadata(sbi, 0, &offset, &size);
+               if (IS_ERR(data)) {
+                       ret = PTR_ERR(data);
+                       break;
+               }
+
+               ret = 0;
+               free(data);
+               if (ret)
+                       break;
+       }
+       return ret;
+}
index 4d16d29a57b9d8fae92e070d659d0b772820b21a..61a1618bfd4dd6954fcd319c51c243f35675deda 100644 (file)
@@ -126,10 +126,9 @@ int erofs_read_superblock(struct erofs_sb_info *sbi)
 
        memcpy(&sbi->uuid, dsb->uuid, sizeof(dsb->uuid));
 
-       if (erofs_sb_has_compr_cfgs(sbi))
-               sbi->available_compr_algs = le16_to_cpu(dsb->u1.available_compr_algs);
-       else
-               sbi->lz4_max_distance = le16_to_cpu(dsb->u1.lz4_max_distance);
+       ret = z_erofs_parse_cfgs(sbi, dsb);
+       if (ret)
+               return ret;
 
        ret = erofs_init_devices(sbi, dsb);
        if (ret)