Patchwork UBI/ubifs problem

login
register
mail settings
Submitter Artem Bityutskiy
Date March 7, 2012, 2:40 p.m.
Message ID <1331131250.32316.8.camel@sauron.fi.intel.com>
Download mbox | patch
Permalink /patch/145301/
State New
Headers show

Comments

Artem Bityutskiy - March 7, 2012, 2:40 p.m.
On Fri, 2012-02-17 at 11:13 +0100, Ricard Wanderlof wrote:
> Yesterday I reported a problem I had when flashing a ubifs volume.
> 
> On Thu, 16 Feb 2012, Ricard Wanderlof wrote:
> 
> > ...
> > UBIFS error (pid 2965): validate_sb: bad superblock, error 8
> > mount: Mounting ubi0:rwfs on /mnt/2 failed: Invalid argument
> > ...
> 
> I think I've figured this out part way. I've been specifying a 
> --max-leb-count of 1000 to mkfs.ubifs, thinking that it basically just 
> sets a maximum size for the resulting file system. But it seems that it 
> also sets some sort of bounds for how much space it expects to take up in 
> the volume. If I reduce the --max-leb-count to the size of the target 
> volume, I get no errors and the file system mounts fine.

When you specify --max-leb-count=1000, but not specify the journal size,
mkfs.ubifs defines the journal size to be around 12% of that, but not
larger than 8MiB. This sets the low UBI volume size boundary.

So basically the error you get means that your UBI volume is too small
to fit the journal.

To see the journal size of your image use -v mkfs.ubifs option when you
generate it.

You can define your own journal size using the --jrn-size mkfs.ubifs
option.

> That being so, I think the resulting error message is odd, which indicates 
> there is a bug somewhere, probably in mkfs.ubifs ?

I agree that the message is odd. Below is the patch which I'll push to
linux-ubifs.git as soon as git.infradead.org is available (it is down
now for the reasons I do not know). I am open to additional or different
suggestions. Thanks!

P.S. I did not even compile - test the below patch, but will push out a
tested version.

From: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Date: Wed, 7 Mar 2012 16:29:45 +0200
Subject: [PATCH] UBIFS: improve error messages

Ricard complaints that the following error message is odd:

"UBIFS error (pid 1578): validate_sb: bad superblock, error 8"

and he is right. This patch improves the error messages a bit and makes
them more user-friendly.

Reported-by: Ricard Wanderlof <ricard.wanderlof@axis.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
---
 fs/ubifs/sb.c |   19 ++++++++++++++-----
 1 files changed, 14 insertions(+), 5 deletions(-)
Ricard Wanderlof - March 7, 2012, 4:26 p.m.
On Wed, 7 Mar 2012, Artem Bityutskiy wrote:

> When you specify --max-leb-count=1000, but not specify the journal size,
> mkfs.ubifs defines the journal size to be around 12% of that, but not
> larger than 8MiB. This sets the low UBI volume size boundary.
>
> So basically the error you get means that your UBI volume is too small
> to fit the journal.
>
> To see the journal size of your image use -v mkfs.ubifs option when you
> generate it.
>
> You can define your own journal size using the --jrn-size mkfs.ubifs 
> option.

Is it possible to get mkfs.ubifs to create an image without specifying the 
max-leb-count ? I.e. just to create an image that is as big as it has to 
be. Admittedly, one would have to figure out the size of the resulting 
volume afterwards, to provide an allocation size for ubimkvol or ubinize, 
so perhaps it would help much.

>> That being so, I think the resulting error message is odd, which indicates
>> there is a bug somewhere, probably in mkfs.ubifs ?
>
> I agree that the message is odd. Below is the patch which I'll push to
> linux-ubifs.git as soon as git.infradead.org is available (it is down
> now for the reasons I do not know). I am open to additional or different
> suggestions. Thanks!
>
> P.S. I did not even compile - test the below patch, but will push out a
> tested version.

Thanks for the patch, I'll try to test it.

/Ricard
Paul Parsons - March 7, 2012, 4:51 p.m.
--- On Wed, 7/3/12, Ricard Wanderlof <ricard.wanderlof@axis.com> wrote:
> Is it possible to get mkfs.ubifs to create an image without
> specifying the max-leb-count ? I.e. just to create an image
> that is as big as it has to be. Admittedly, one would have
> to figure out the size of the resulting volume afterwards,
> to provide an allocation size for ubimkvol or ubinize, so
> perhaps it would help much.

When I first started to try out UBI/UBIFS I had problems understanding the
arithmetic, and it took several attempts to get it working.

In the end I created a simple shell script to do all the hard work for me.

Given the UBI MTD partition size, PEB size, and desired volume sizes, the
script would do the rest:

#!/bin/bash

#
#	Create UBI for 125MiB MTD on NOR flash, consisting of:
#
#		UBI overhead.
#		Volume 0: rootfs, 75MiB less UBI overhead.
#		Volume 1: homefs, 50MiB.
#

declare -r rootimg="rootfs.img"
declare -r homeimg="homefs.img"
declare -r ipaqcfg="ipaq.cfg"

declare -ir KiB=1024
declare -ir MiB=$((1024*1024))

declare -i UBI=$((125*MiB))			# UBI size
declare -i Sp=$((256*KiB))			# PEB size
declare -i P=$((UBI/Sp))			# Total number of PEBs
declare -i O=128				# EC header + VID header overhead
declare -i Sl=$((Sp-O))				# LEB size
declare -i B=0					# NOR does not have bad PEBs
declare -i U=$((((B+4)*Sp)+(O*(P-B-4))))	# UBI overhead
declare -i Ur=$(((U+Sp-1)&(~(Sp-1))))		# UBI overhead rounded up to next PEB size

declare -i ROOTFS=$(((75*MiB)-Ur))		# rootfs size
declare -i HOMEFS=$((50*MiB))			# homefs size

cmd="mkfs.ubifs --root=rootfs --output=${rootimg} -m 1 -e ${Sl} -c $((ROOTFS/Sp)) -x none"
echo ${cmd}
${cmd} || exit 1

cmd="mkfs.ubifs --root=homefs --output=${homeimg} -m 1 -e ${Sl} -c $((HOMEFS/Sp)) -x none"
echo ${cmd}
${cmd} || exit 1

rm -f ${ipaqcfg}
echo "[rootfs]" >> ${ipaqcfg}
echo "mode=ubi" >> ${ipaqcfg}
echo "image=${rootimg}" >> ${ipaqcfg}
echo "vol_id=0" >> ${ipaqcfg}
echo "vol_size=$((((ROOTFS)/Sp)*Sl))" >> ${ipaqcfg}
echo "vol_type=dynamic" >> ${ipaqcfg}
echo "vol_name=rootfs" >> ${ipaqcfg}
echo "[homefs]" >> ${ipaqcfg}
echo "mode=ubi" >> ${ipaqcfg}
echo "image=${homeimg}" >> ${ipaqcfg}
echo "vol_id=1" >> ${ipaqcfg}
echo "vol_size=$((((HOMEFS)/Sp)*Sl))" >> ${ipaqcfg}
echo "vol_type=dynamic" >> ${ipaqcfg}
echo "vol_name=homefs" >> ${ipaqcfg}

cmd="ubinize -o ipaq.ubi -p ${Sp} -m 1 -v ${ipaqcfg}"
echo ${cmd}
${cmd} || exit 1

It works for me. Hopefully it might be useful to others.

Patch

diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c
index 6094c5a..4d4ef12 100644
--- a/fs/ubifs/sb.c
+++ b/fs/ubifs/sb.c
@@ -410,13 +410,23 @@  static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup)
 	}
 
 	if (c->main_lebs < UBIFS_MIN_MAIN_LEBS) {
-		err = 7;
+		ubifs_err("too few main LEBs count %d, must be at least %d",
+			  c->main_lebs, UBIFS_MIN_MAIN_LEBS);
 		goto failed;
 	}
 
-	if (c->max_bud_bytes < (long long)c->leb_size * UBIFS_MIN_BUD_LEBS ||
-	    c->max_bud_bytes > (long long)c->leb_size * c->main_lebs) {
-		err = 8;
+	max_bytes = (long long)c->leb_size * UBIFS_MIN_BUD_LEBS;
+	if (c->max_bud_bytes < max_bytes) {
+		ubifs_err("too small journal (%lld bytes), must be at least ""
+			  %lld bytes",  c->max_bud_bytes, max_bytes);
+		goto failed;
+	}
+
+	max_bytes = (long long)c->leb_size * c->main_lebs;
+	if (c->max_bud_bytes > max_bytes) {
+		ubifs_err("too large journal size (%lld bytes), only %lld bytes"
+			  "available in the main area",
+			  c->max_bud_bytes, max_bytes);
 		goto failed;
 	}
 
@@ -450,7 +460,6 @@  static int validate_sb(struct ubifs_info *c, struct ubifs_sb_node *sup)
 		goto failed;
 	}
 
-	max_bytes = c->main_lebs * (long long)c->leb_size;
 	if (c->rp_size < 0 || max_bytes < c->rp_size) {
 		err = 14;
 		goto failed;