[PATCH] mkfs.ubifs: Add option to minimize the amount of LEBs

Mauri Sandberg maukka at ext.kapsi.fi
Fri Dec 29 05:56:53 PST 2023


Use case for the new option would be when you want to have a
non-mutable filesystem in a static ubifs volume and another
volume for writable data.

Currently you can find the minimal LEB count by running the
mkfs.ubifs once with too small max_leb_cnt. This patch uses
the already calculated minimal amount of LEBs as the max_leb_cnt
and then proceeds to create the image as usual.

Signed-off-by: Mauri Sandberg <maukka at ext.kapsi.fi>
---
 ubifs-utils/mkfs.ubifs/mkfs.ubifs.c | 40 +++++++++++++++++++++--------
 1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
index 8f8d40b..02ca337 100644
--- a/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
+++ b/ubifs-utils/mkfs.ubifs/mkfs.ubifs.c
@@ -141,6 +141,7 @@ static int do_create_inum_attr;
 static char *context;
 static int context_len;
 static struct stat context_st;
+static int minimize;
 
 /* The 'head' (position) which nodes are written */
 static int head_lnum;
@@ -163,7 +164,7 @@ static struct inum_mapping **hash_table;
 /* Inode creation sequence number */
 static unsigned long long creat_sqnum;
 
-static const char *optstring = "d:r:m:o:D:yh?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQqaK:b:P:C:";
+static const char *optstring = "d:r:m:o:D:yh?vVe:c:g:f:Fp:k:x:X:j:R:l:j:UQqaK:b:P:C:M";
 
 enum {
 	HASH_ALGO_OPTION = CHAR_MAX + 1,
@@ -202,6 +203,7 @@ static const struct option longopts[] = {
 	{"hash-algo",          1, NULL, HASH_ALGO_OPTION},
 	{"auth-key",           1, NULL, AUTH_KEY_OPTION},
 	{"auth-cert",          1, NULL, AUTH_CERT_OPTION},
+	{"minimize-lebs",      0, NULL, 'M'},
 	{NULL, 0, NULL, 0}
 };
 
@@ -258,6 +260,7 @@ static const char *helptext =
 "                         for signing\n"
 "    --auth-cert=FILE     Authentication certificate filename for signing. Unused\n"
 "                         when certificate is provided via PKCS #11\n"
+"-M  --minimize-lebs      use minimal amount of LEBs\n"
 "-h, --help               display this help text\n\n"
 "Note, SIZE is specified in bytes, but it may also be specified in Kilobytes,\n"
 "Megabytes, and Gigabytes if a KiB, MiB, or GiB suffix is used.\n\n"
@@ -420,8 +423,11 @@ static int validate_options(void)
 		return err_msg("too large LEB size %d, maximum is %d",
 				c->leb_size, UBIFS_MAX_LEB_SZ);
 	if (c->max_leb_cnt < UBIFS_MIN_LEB_CNT)
-		return err_msg("too low max. count of LEBs, minimum is %d",
-			       UBIFS_MIN_LEB_CNT);
+		if (minimize)
+			c->max_leb_cnt = UBIFS_MIN_LEB_CNT;
+		else
+			return err_msg("too low max. count of LEBs, minimum is %d",
+				       UBIFS_MIN_LEB_CNT);
 	if (c->fanout < UBIFS_MIN_FANOUT)
 		return err_msg("too low fanout, minimum is %d",
 			       UBIFS_MIN_FANOUT);
@@ -432,13 +438,13 @@ static int validate_options(void)
 	if (c->log_lebs < UBIFS_MIN_LOG_LEBS)
 		return err_msg("too few log LEBs, minimum is %d",
 			       UBIFS_MIN_LOG_LEBS);
-	if (c->log_lebs >= c->max_leb_cnt - UBIFS_MIN_LEB_CNT)
+	if (!minimize && c->log_lebs >= c->max_leb_cnt - UBIFS_MIN_LEB_CNT)
 		return err_msg("too many log LEBs, maximum is %d",
 			       c->max_leb_cnt - UBIFS_MIN_LEB_CNT);
 	if (c->orph_lebs < UBIFS_MIN_ORPH_LEBS)
 		return err_msg("too few orphan LEBs, minimum is %d",
 			       UBIFS_MIN_ORPH_LEBS);
-	if (c->orph_lebs >= c->max_leb_cnt - UBIFS_MIN_LEB_CNT)
+	if (!minimize && c->orph_lebs >= c->max_leb_cnt - UBIFS_MIN_LEB_CNT)
 		return err_msg("too many orphan LEBs, maximum is %d",
 			       c->max_leb_cnt - UBIFS_MIN_LEB_CNT);
 	tmp = UBIFS_SB_LEBS + UBIFS_MST_LEBS + c->log_lebs + c->lpt_lebs;
@@ -800,6 +806,9 @@ static int get_options(int argc, char**argv)
 		case AUTH_CERT_OPTION:
 			return err_msg("mkfs.ubifs was built without crypto support.");
 #endif
+		case 'M':
+			minimize = 1;
+			break;
 		}
 	}
 
@@ -847,8 +856,12 @@ static int get_options(int argc, char**argv)
 	if (c->leb_size == -1)
 		return err_msg("LEB size was not specified (use -h for help)");
 
-	if (c->max_leb_cnt == -1)
-		return err_msg("Maximum count of LEBs was not specified "
+	if (!minimize && c->max_leb_cnt == -1)
+		return err_msg("Maximum count of LEBs or --minimize-lebs was not specified "
+			       "(use -h for help)");
+
+	if (minimize && c->max_leb_cnt != -1)
+		return err_msg("You have to specify either --minimize-lebs or --max-leb-cnt "
 			       "(use -h for help)");
 
 	if (c->max_bud_bytes == -1) {
@@ -876,7 +889,8 @@ static int get_options(int argc, char**argv)
 
 	if (c->log_lebs == -1) {
 		c->log_lebs = calc_min_log_lebs(c->max_bud_bytes);
-		c->log_lebs += 2;
+		if (!minimize)
+			c->log_lebs += 2;
 	}
 
 	if (c->min_io_size < 8)
@@ -888,7 +902,10 @@ static int get_options(int argc, char**argv)
 		printf("\troot:         %s\n", root);
 		printf("\tmin_io_size:  %d\n", c->min_io_size);
 		printf("\tleb_size:     %d\n", c->leb_size);
-		printf("\tmax_leb_cnt:  %d\n", c->max_leb_cnt);
+		if (minimize)
+			printf("\tminimize:     %d\n", minimize);
+		else
+			printf("\tmax_leb_cnt:  %d\n", c->max_leb_cnt);
 		printf("\toutput:       %s\n", output);
 		printf("\tjrn_size:     %llu\n", c->max_bud_bytes);
 		printf("\treserved:     %llu\n", c->rp_size);
@@ -2553,7 +2570,10 @@ static int finalize_leb_cnt(void)
 {
 	c->leb_cnt = head_lnum;
 	if (c->leb_cnt > c->max_leb_cnt)
-		return err_msg("max_leb_cnt too low (%d needed)", c->leb_cnt);
+		if (minimize)
+			c->max_leb_cnt = c->leb_cnt;
+		else
+			return err_msg("max_leb_cnt too low (%d needed)", c->leb_cnt);
 	c->main_lebs = c->leb_cnt - c->main_first;
 	if (verbose) {
 		printf("\tsuper lebs:   %d\n", UBIFS_SB_LEBS);

base-commit: 9471c13faf76ff05f58d636b988bb066ad6d05fa
-- 
2.34.1




More information about the linux-mtd mailing list