[PATCH 1/2] erofs-utils: introduce z_erofs_parse_cfgs()

Gao Xiang hsiangkao at linux.alibaba.com
Wed Jun 5 22:14:47 AEST 2024


This userspace implementation will be mainly used for the upcoming
Intel In-Memory Analytics Accelerator integration.

Signed-off-by: Gao Xiang <hsiangkao at 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.39.3



More information about the Linux-erofs mailing list