UBI-FS Master Node failure

David J Myers david.myers at amg-panogenics.com
Mon Jun 22 01:01:48 PDT 2015


Guys,
I have an embedded product running a system based on linux-2.6.29,
originally from the IC supplier, but patched and modified to our spec.
Recently we have had two units go down with the same UBI-FS Master Node
failure, both in LEB-2 at slightly different offsets. The console log looks
like this:-

[    6.645845] UBIFS error (pid 1): ubifs_scan: corrupt empty space at LEB
2:86016
[    6.653268] UBIFS error (pid 1): ubifs_scanned_corruption: corrupted data
at LEB 2:86016
[    6.668163] UBIFS error (pid 1): ubifs_scan: LEB 2 scanning failed
[    6.889661] UBIFS error (pid 1): ubifs_recover_master_node: failed to
recover master node
[    6.898497] List of all partitions:
[    6.902188] 1f00             128 mtdblock0 (driver?)
[    6.907218] 1f01             768 mtdblock1 (driver?)
[    6.912314] 1f02             128 mtdblock2 (driver?)
[    6.917318] 1f03            4096 mtdblock3 (driver?)
[    6.922395] 1f04            4096 mtdblock4 (driver?)
[    6.927397] 1f05           65536 mtdblock5 (driver?)
[    6.932464] 1f06          184320 mtdblock6 (driver?)
[    6.937455] No filesystem could mount root, tried:  ubifs
[    6.942988] Kernel panic - not syncing: VFS: Unable to mount root fs on
unknown-block(0,0)

I found two patches to fs/ubifs/recovery.c since 2.6.29 which I applied, but
they did not fix the corrupted flash. These two patches were this one:-

diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index f94ddf7..31d09d1 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -299,6 +299,32 @@ int ubifs_recover_master_node(struct ubifs_info *c)
                      goto out_free;
              }
              memcpy(c->rcvrd_mst_node, c->mst_node, UBIFS_MST_NODE_SZ);
+
+              /*
+              * We had to recover the master node, which means there was an
+              * unclean reboot. However, it is possible that the master
node
+              * is clean at this point, i.e., %UBIFS_MST_DIRTY is not set.
+              * E.g., consider the following chain of events:
+              *
+              * 1. UBIFS was cleanly unmounted, so the master node is clean
+              * 2. UBIFS is being mounted R/W and starts changing the
master
+              *    node in the first (%UBIFS_MST_LNUM). A power cut
happens,
+              *    so this LEB ends up with some amount of garbage at the
+              *    end.
+              * 3. UBIFS is being mounted R/O. We reach this place and
+              *    recover the master node from the second LEB
+              *    (%UBIFS_MST_LNUM + 1). But we cannot update the media
+              *    because we are being mounted R/O. We have to defer the
+              *    operation.
+              * 4. However, this master node (@c->mst_node) is marked as
+              *    clean (since the step 1). And if we just return, the
+              *    mount code will be confused and won't recover the master
+              *    node when it is re-mounter R/W later.
+              *
+              *    Thus, to force the recovery by marking the master node
as
+              *    dirty.
+              */
+              c->mst_node->flags |= cpu_to_le32(UBIFS_MST_DIRTY);
       } else {
              /* Write the recovered master node */
              c->max_sqnum = le64_to_cpu(mst->ch.sqnum) - 1;
-- 
1.7.10.2

And this one:-
> diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
> index 5256f42..2c98d77 100644
> --- a/fs/ubifs/recovery.c
> +++ b/fs/ubifs/recovery.c
> @@ -273,7 +273,8 @@ int ubifs_recover_master_node(struct ubifs_info *c)
>                              if (cor1)
>                                     goto out_err;
>                              mst = mst1;
> -                    } else if (offs1 == 0 && offs2 + sz >= c->leb_size) {
> +                    } else if (offs1 == 0 &&
> +                               c->leb_size - offs2 - sz < sz) {
>                              /* 1st LEB was unmapped and written, 2nd not
*/
>                              if (cor1)
>                                     goto out_err;
>

Please advise.
-	J






More information about the linux-mtd mailing list