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

Mauri Sandberg maukka at ext.kapsi.fi
Fri Jan 5 22:49:18 PST 2024



On 29.12.2023 15.56, Mauri Sandberg wrote:
> 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

Friendly ping. Also bringing in Richard and David as I thought at least
they could be relevant maintainers. Thanks.



More information about the linux-mtd mailing list