[PATCH 2/2] erofs-utils: mkfs: allow multiplier suffixes ('K', 'M', 'G')

Gao Xiang hsiangkao at linux.alibaba.com
Wed Feb 18 15:54:07 AEDT 2026


Apply to common arguments such as `-b`, `-C` and `-m`.

Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 mkfs/main.c | 111 +++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 96 insertions(+), 15 deletions(-)

diff --git a/mkfs/main.c b/mkfs/main.c
index fb51cf87ef48..d909ef1a5834 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -748,6 +748,82 @@ static int mkfs_parse_s3_cfg(char *cfg_str)
 }
 #endif
 
+static int erofs_mkfs_strtoll(const char *nptr, char **endptr,
+			      long long *res, int base)
+{
+	char *end;
+	long long number;
+
+	errno = 0;
+	number = strtoll(nptr, &end, base);
+	if (errno)
+		return -errno;
+
+	if (*end == 'k' || *end == 'K')
+		number *= 1024, ++end;
+	else if (*end == 'm' || *end == 'M')
+		number *= 1048576, ++end;
+	else if (*end == 'g' || *end == 'G')
+		number *= 1073741824, ++end;
+	*res = number;
+	if (endptr)
+		*endptr = end;
+	return 0;
+}
+
+static int erofs_mkfs_strtol(const char *nptr, char **endptr,
+			     long *res, int base)
+{
+	long long res_ll;
+	int ret;
+
+	ret = erofs_mkfs_strtoll(nptr, endptr, &res_ll, base);
+	if (ret)
+		return ret;
+	if (res_ll > LONG_MAX || res_ll < LONG_MIN)
+		return -ERANGE;
+	*res = res_ll;
+	return 0;
+}
+
+static int erofs_mkfs_strtoull(const char *nptr, char **endptr,
+			       unsigned long long *res, int base)
+{
+	char *end;
+	unsigned long long number;
+
+	errno = 0;
+	number = strtoull(nptr, &end, base);
+	if (errno)
+		return -errno;
+
+	if (*end == 'k' || *end == 'K')
+		number <<= 10, ++end;
+	else if (*end == 'm' || *end == 'M')
+		number <<= 20, ++end;
+	else if (*end == 'g' || *end == 'G')
+		number <<= 30, ++end;
+	*res = number;
+	if (endptr)
+		*endptr = end;
+	return 0;
+}
+
+static int erofs_mkfs_strtou32(const char *nptr, char **endptr,
+			       u32 *res, int base)
+{
+	unsigned long long res_ull;
+	int ret;
+
+	ret = erofs_mkfs_strtoull(nptr, endptr, &res_ull, base);
+	if (ret)
+		return ret;
+	if (res_ull > UINT32_MAX)
+		return -ERANGE;
+	*res = res_ull;
+	return 0;
+}
+
 #ifdef OCIEROFS_ENABLED
 /*
  * mkfs_parse_oci_options - Parse comma-separated OCI options string
@@ -765,6 +841,7 @@ static int mkfs_parse_oci_options(struct ocierofs_config *oci_cfg, char *options
 {
 	char *opt, *q, *p;
 	long idx;
+	int ret;
 
 	if (!options_str)
 		return 0;
@@ -815,8 +892,8 @@ static int mkfs_parse_oci_options(struct ocierofs_config *oci_cfg, char *options
 				erofs_err("invalid --oci: layer and blob cannot be set together");
 				return -EINVAL;
 			}
-			idx = strtol(p, NULL, 10);
-			if (idx < 0)
+			ret = erofs_mkfs_strtol(p, NULL, &idx, 10);
+			if (ret || idx < 0)
 				return -EINVAL;
 			oci_cfg->layer_index = (int)idx;
 		} else if ((p = strstr(opt, "username="))) {
@@ -890,12 +967,8 @@ static int mkfs_parse_one_compress_alg(char *alg)
 					}
 				} else if ((p = strstr(opt, "dictsize="))) {
 					p += strlen("dictsize=");
-					zset->dict_size = strtoul(p, &endptr, 10);
-					if (*endptr == 'k' || *endptr == 'K')
-						zset->dict_size <<= 10;
-					else if (*endptr == 'm' || *endptr == 'M')
-						zset->dict_size <<= 20;
-					else if ((endptr == p) || (*endptr && *endptr != ',')) {
+					j = erofs_mkfs_strtou32(p, &endptr, &zset->dict_size, 0);
+					if (j < 0 || (*endptr != '\0' && endptr != q)) {
 						erofs_err("invalid compression dictsize %s", p);
 						return -EINVAL;
 					}
@@ -1069,8 +1142,9 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
 			break;
 
 		case 'b':
-			i = atoi(optarg);
-			if (i < 512 || i > EROFS_MAX_BLOCK_SIZE) {
+			err = erofs_mkfs_strtol(optarg, &endptr, &i, 0);
+			if (err || *endptr != '\0' || i < 512 ||
+			    i > EROFS_MAX_BLOCK_SIZE) {
 				erofs_err("invalid block size %s", optarg);
 				return -EINVAL;
 			}
@@ -1179,8 +1253,9 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
 			break;
 #endif
 		case 9:
-			i = strtol(optarg, &endptr, 0);
-			if (*endptr != '\0' || i > INT32_MAX || i < INT32_MIN) {
+			err = erofs_mkfs_strtol(optarg, &endptr, &i, 0);
+			if (err || *endptr != '\0' ||
+			    i > INT32_MAX || i < INT32_MIN) {
 				erofs_err("invalid maximum compressed extent size %s",
 					  optarg);
 				return -EINVAL;
@@ -1206,8 +1281,8 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
 			break;
 #endif
 		case 'C':
-			i = strtoull(optarg, &endptr, 0);
-			if (*endptr != '\0') {
+			err = erofs_mkfs_strtol(optarg, &endptr, &i, 0);
+			if (err < 0 || *endptr != '\0' || i <= 0) {
 				erofs_err("invalid physical clustersize %s",
 					  optarg);
 				return -EINVAL;
@@ -1228,7 +1303,13 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
 					metabox_algorithmid = err;
 				}
 			}
-			pclustersize_metabox = atoi(optarg);
+			err = erofs_mkfs_strtol(optarg, &endptr, &i, 0);
+			if (err < 0 || (*endptr != '\0' && algid != endptr) ||
+			    i <= 0) {
+				erofs_err("invalid metabox option %s", optarg);
+				return -EINVAL;
+			}
+			pclustersize_metabox = i;
 			break;
 		}
 
-- 
2.43.5



More information about the Linux-erofs mailing list