Patchwork ubifs : corruption after power cut test

login
register
mail settings
Submitter Matthieu CASTET
Date July 13, 2010, 9:24 a.m.
Message ID <4C3C30D1.9030005@parrot.com>
Download mbox | patch
Permalink /patch/58720/
State New
Headers show

Comments

Matthieu CASTET - July 13, 2010, 9:24 a.m.
Matthieu CASTET a écrit :
> Matthieu CASTET a écrit :
>> Hi,
>>
>> we found some bug in our driver. Now there no more ubifs error when
>> there is uncorrectable ecc error (they should happen in the last
>> (interrupted) written page).
>>
>> But now we got "validate_master: bad master node at offset 69632 error
>> 7" [1].
> notice that gc_lnum==-1 in this case.
> Also this didn't happen on power cut.
> The senario was :
> - power cut
> - mount fs [1]
> - do some fs operation
> - umount fs quickly (9 second after mount in this case) [2]
> - mount fs [3]
> 
> The the problem seems that gc_lnum==-1 is not handled in mount or
> shouldn't happen in umount.
> 
The attached patch try to support mount with gc_lnum == -1.

Does it look sane ?


Matthieu

Patch

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index eb532e0..56de77f 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -1320,18 +1322,27 @@  static int mount_ubifs(struct ubifs_info *c)
 			if (err)
 				goto out_orphans;
 			err = ubifs_rcvry_gc_commit(c);
-		} else {
-			err = take_gc_lnum(c);
 			if (err)
 				goto out_orphans;
+		} else {
+			if (c->gc_lnum == -1) {
+				err = ubifs_rcvry_gc_commit(c);
+				if (err)
+					goto out_orphans;
+			}
+			else {
+				err = take_gc_lnum(c);
+				if (err)
+					goto out_orphans;
 
-			/*
-			 * GC LEB may contain garbage if there was an unclean
-			 * reboot, and it should be un-mapped.
-			 */
-			err = ubifs_leb_unmap(c, c->gc_lnum);
-			if (err)
-				return err;
+				/*
+				 * GC LEB may contain garbage if there was an unclean
+				 * reboot, and it should be un-mapped.
+				 */
+				err = ubifs_leb_unmap(c, c->gc_lnum);
+				if (err)
+					return err;
+			}
 		}
 
 		err = dbg_check_lprops(c);
diff --git a/fs/ubifs/master.c b/fs/ubifs/master.c
index 28beaee..8d5b080 100644
--- a/fs/ubifs/master.c
+++ b/fs/ubifs/master.c
@@ -135,7 +135,7 @@  static int validate_master(const struct ubifs_info *c)
 		goto out;
 	}
 
-	if (c->gc_lnum >= c->leb_cnt || c->gc_lnum < c->main_first) {
+	if (c->gc_lnum != -1 && (c->gc_lnum >= c->leb_cnt || c->gc_lnum < c->main_first)) {
 		err = 7;
 		goto out;
 	}