From fe80239ed26da46771d432b1b83c70f5f1841aa8 Mon Sep 17 00:00:00 2001 From: Gao Xiang Date: Wed, 5 Jun 2024 20:14:47 +0800 Subject: [PATCH] erofs-utils: introduce z_erofs_parse_cfgs() This userspace implementation will be mainly used for the upcoming Intel In-Memory Analytics Accelerator integration. Signed-off-by: Gao Xiang Link: https://lore.kernel.org/r/20240605121448.3816160-1-hsiangkao@linux.alibaba.com --- include/erofs/internal.h | 1 + lib/decompress.c | 41 ++++++++++++++++++++++++++++++++++++++++ lib/super.c | 7 +++---- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/include/erofs/internal.h b/include/erofs/internal.h index 9fdff71..d52bcc6 100644 --- a/include/erofs/internal.h +++ b/include/erofs/internal.h @@ -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) diff --git a/lib/decompress.c b/lib/decompress.c index e65b924..2842f51 100644 --- a/lib/decompress.c +++ b/lib/decompress.c @@ -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; +} diff --git a/lib/super.c b/lib/super.c index 4d16d29..61a1618 100644 --- a/lib/super.c +++ b/lib/super.c @@ -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) -- 2.34.1