Patchwork UBIFS Corrupt during power failure

login
register
mail settings
Submitter Eric Holmberg
Date July 28, 2009, 5:19 p.m.
Message ID <C77C279BA71FD14985DC8E75FB265AB703C97962@usw-am-xch-02.am.trimblecorp.net>
Download mbox | patch
Permalink /patch/30310/
State New
Headers show

Comments

Eric Holmberg - July 28, 2009, 5:19 p.m.
> We have similar problems with a SPANSION falsh (S29GL01GP).
> I think the reason of the problem is a feature of the chip.
> 
> I reduced the problem to the MTD access (without ubi/ubifs).
> We noticed toggle flash-bit(s) after power off during a write cycle.
> The toggle flash-bit(s) may occure after power of during an 
> sector-erase
> too.
> 
> Simple testsequence:
> * flash_erase ...
> * cp testfile /dev/mtd0
> - automatic or manuel power off during the cp
> Check the flash after reboot (e.g md5sum /dev/mtd0 helps).
> 
> We used the default settings from the CFI (MaxBufWriteSize=6 
> == 64 byte
> buffer).

I think writing to /dev/mtd0 will also perform an erase if needed, so
you are probably seeing the interrupted erase.

If you're doing this because you are having UBIFS errors, then you
should set the MaxBufWriteSize to 3 to limit the write size to 2^3=8
bytes since this is a known problem.

Here's the patch (it's also attached to this email) for the debug code
that I added to limit the write buffer size to 2**3=8 bytes and have
been using for all of the recent robustness testing.

I'm using the S29GL256 chip (256Mbit) which is in the same family as
your S29GL01G (1Gbit), so with this patch and the latest patches from
http://git.infradead.org/users/dedekind/ubifs-v2.6.27.git should get you
to the same place that I'm at.  So far, with over 10,000 power cycles, I
haven't seen any problems.

-Eric

 #ifdef DEBUG_CFI
 	/* Dump the information therein */
 	print_cfi_ident(cfi->cfiq);

Patch

Index: drivers/mtd/chips/cfi_probe.c
===================================================================
--- drivers/mtd/chips/cfi_probe.c	(revision 4477)
+++ drivers/mtd/chips/cfi_probe.c	(working copy)
@@ -18,7 +18,7 @@ 
 #include <linux/mtd/cfi.h>
 #include <linux/mtd/gen_probe.h>
 
-//#define DEBUG_CFI
+#define DEBUG_CFI
 
 #ifdef DEBUG_CFI
 static void print_cfi_ident(struct cfi_ident *);
@@ -251,6 +251,18 @@ 
 	cfi->cfiq->InterfaceDesc =
le16_to_cpu(cfi->cfiq->InterfaceDesc);
 	cfi->cfiq->MaxBufWriteSize =
le16_to_cpu(cfi->cfiq->MaxBufWriteSize);
 
+	//DEBUG - BEGIN - force max write size to 8 bytes (2^3)
+	if (cfi->cfiq->MaxBufWriteSize)
+	{
+		printk("Warning:  Overriding MaxBufWriteSize from 2^%d
to 2^%d\n",
+				cfi->cfiq->MaxBufWriteSize,
+				3
+				);
+		cfi->cfiq->MaxBufWriteSize = 3;
+	}
+	//DEBUG - END
+
+