[PATCH 4/4] erofs-utils: support subpage block sizes

Gao Xiang hsiangkao at linux.alibaba.com
Tue Mar 14 14:38:14 AEDT 2023


 - Add a new command option for mkfs.erofs.

 - erofsfuse supports subpage block sizes (uncompressed files).

Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 lib/namei.c |  5 ++++-
 lib/super.c | 13 +++++--------
 mkfs/main.c | 27 +++++++++++++++++++++++----
 3 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/lib/namei.c b/lib/namei.c
index 6ee4925..3d0cf93 100644
--- a/lib/namei.c
+++ b/lib/namei.c
@@ -136,8 +136,11 @@ int erofs_read_inode_from_disk(struct erofs_inode *vi)
 		}
 		vi->u.chunkbits = sbi.blkszbits +
 			(vi->u.chunkformat & EROFS_CHUNK_FORMAT_BLKBITS_MASK);
-	} else if (erofs_inode_is_data_compressed(vi->datalayout))
+	} else if (erofs_inode_is_data_compressed(vi->datalayout)) {
+		if (erofs_blksiz() != PAGE_SIZE)
+			return -EOPNOTSUPP;
 		return z_erofs_fill_inode(vi);
+	}
 	return 0;
 bogusimode:
 	erofs_err("bogus i_mode (%o) @ nid %llu", vi->i_mode, vi->nid | 0ULL);
diff --git a/lib/super.c b/lib/super.c
index ccf3ef1..e711c6c 100644
--- a/lib/super.c
+++ b/lib/super.c
@@ -68,12 +68,11 @@ static int erofs_init_devices(struct erofs_sb_info *sbi,
 
 int erofs_read_superblock(void)
 {
-	char data[EROFS_MAX_BLOCK_SIZE];
+	u8 data[EROFS_MAX_BLOCK_SIZE];
 	struct erofs_super_block *dsb;
-	unsigned int blkszbits;
 	int ret;
 
-	ret = blk_read(0, data, 0, 1);
+	ret = blk_read(0, data, 0, erofs_blknr(sizeof(data)));
 	if (ret < 0) {
 		erofs_err("cannot read erofs superblock: %d", ret);
 		return -EIO;
@@ -87,12 +86,10 @@ int erofs_read_superblock(void)
 	}
 
 	sbi.feature_compat = le32_to_cpu(dsb->feature_compat);
-
-	blkszbits = dsb->blkszbits;
-	/* 9(512 bytes) + LOG_SECTORS_PER_BLOCK == sbi.blkszbits */
-	if (blkszbits != sbi.blkszbits) {
+	sbi.blkszbits = dsb->blkszbits;
+	if (sbi.blkszbits < 9) {
 		erofs_err("blksize %d isn't supported on this platform",
-			  1 << blkszbits);
+			  1 << sbi.blkszbits);
 		return ret;
 	}
 
diff --git a/mkfs/main.c b/mkfs/main.c
index b4e4c8d..f4d2330 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -82,6 +82,7 @@ static void usage(void)
 {
 	fputs("usage: [options] FILE DIRECTORY\n\n"
 	      "Generate erofs image from DIRECTORY to FILE, and [options] are:\n"
+	      " -b#                   set block size to # (# = page size by default)\n"
 	      " -d#                   set output message level to # (maximum 9)\n"
 	      " -x#                   set xattr tolerance to # (< 0, disable xattrs; default 2)\n"
 	      " -zX[,Y][:..]          X=compressor (Y=compression level, optional)\n"
@@ -273,7 +274,7 @@ static int mkfs_parse_options_cfg(int argc, char *argv[])
 	int opt, i;
 	bool quiet = false;
 
-	while ((opt = getopt_long(argc, argv, "C:E:L:T:U:d:x:z:",
+	while ((opt = getopt_long(argc, argv, "C:E:L:T:U:b:d:x:z:",
 				  long_options, NULL)) != -1) {
 		switch (opt) {
 		case 'z':
@@ -287,6 +288,15 @@ static int mkfs_parse_options_cfg(int argc, char *argv[])
 				return i;
 			break;
 
+		case 'b':
+			i = atoi(optarg);
+			if (i < 512 || i > EROFS_MAX_BLOCK_SIZE) {
+				erofs_err("invalid block size %s", optarg);
+				return -EINVAL;
+			}
+			sbi.blkszbits = ilog2(i);
+			break;
+
 		case 'd':
 			i = atoi(optarg);
 			if (i < EROFS_MSG_MIN || i > EROFS_MSG_MAX) {
@@ -515,7 +525,11 @@ static int mkfs_parse_options_cfg(int argc, char *argv[])
 		cfg.c_dbg_lvl = EROFS_ERR;
 		cfg.c_showprogress = false;
 	}
-
+	if (cfg.c_compr_alg[0] && erofs_blksiz() != PAGE_SIZE) {
+		erofs_err("compression is unsupported for now with block size %u",
+			  erofs_blksiz());
+		return -EINVAL;
+	}
 	if (pclustersize_max) {
 		if (pclustersize_max < erofs_blksiz() ||
 		    pclustersize_max % erofs_blksiz()) {
@@ -597,9 +611,10 @@ static int erofs_mkfs_superblock_csum_set(void)
 	int ret;
 	u8 buf[EROFS_MAX_BLOCK_SIZE];
 	u32 crc;
+	unsigned int len;
 	struct erofs_super_block *sb;
 
-	ret = blk_read(0, buf, 0, 1);
+	ret = blk_read(0, buf, 0, erofs_blknr(sizeof(buf)));
 	if (ret) {
 		erofs_err("failed to read superblock to set checksum: %s",
 			  erofs_strerror(ret));
@@ -620,7 +635,11 @@ static int erofs_mkfs_superblock_csum_set(void)
 	/* turn on checksum feature */
 	sb->feature_compat = cpu_to_le32(le32_to_cpu(sb->feature_compat) |
 					 EROFS_FEATURE_COMPAT_SB_CHKSUM);
-	crc = erofs_crc32c(~0, (u8 *)sb, erofs_blksiz() - EROFS_SUPER_OFFSET);
+	if (erofs_blksiz() > EROFS_SUPER_OFFSET)
+		len = erofs_blksiz() - EROFS_SUPER_OFFSET;
+	else
+		len = erofs_blksiz();
+	crc = erofs_crc32c(~0, (u8 *)sb, len);
 
 	/* set up checksum field to erofs_super_block */
 	sb->checksum = cpu_to_le32(crc);
-- 
2.24.4



More information about the Linux-erofs mailing list