[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Checksum handling in jffs_rewrite_data().




dwmw2@xxxxxxx.org said:
> I'll look at cleaning up the behaviour of jffs_scan_flash() when it
> finds  dirty space followed by large amounts of free space. 

This mounts the offending filesystem OK, and looks vaguely sensible. I'll 
try it on some of the other filesystems that have previously caused JFFS to 
fall over by having dirty bytes in strange places (usually due to 
interrupted erase cycles.)

In the meantime, does it look right to you?

Index: intrep.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs/intrep.c,v
retrieving revision 1.68
diff -u -r1.68 intrep.c
--- intrep.c	2000/08/23 11:27:35	1.68
+++ intrep.c	2000/08/24 09:21:41
@@ -686,6 +686,7 @@
 				  "hexdump(pos = 0x%lx, len = 128):\n",
 				  (long)pos));
 			D1(jffs_hexdump(fmc->mtd, pos, 128));
+		cont_dirty:
 			for (pos += 4; pos < end; pos += 4) {
 				switch (flash_read_u32(fmc->mtd, pos)) {
 				case JFFS_MAGIC_BITMASK:
@@ -693,6 +694,46 @@
 						       (__u32) (pos - start),
 						       0);
 					goto cont_scan;
+				case JFFS_EMPTY_BITMASK:
+					/* First, mark as dirty the region
+					   which really does contain crap. */
+					jffs_fmalloced(fmc, (__u32) start,
+						       (__u32) (pos - start),
+						       0);
+
+					/* Then, scan the region which looks free.
+					   Depending on how large it is, we may
+					   mark it dirty too.
+					*/
+					start = pos;
+					for (; pos < end ; pos += 4) {
+						switch (flash_read_u32(fmc->mtd, pos)) {
+						case JFFS_MAGIC_BITMASK:
+							if (pos - start < fmc->max_chunk_size) {
+								/* Not much free space. Mark it dirty. */
+								jffs_fmalloced(fmc, (__u32)start,
+									       (__u32)pos-start, 0);
+							}
+							goto cont_scan;
+
+						case JFFS_EMPTY_BITMASK:
+							/* More empty space */
+							continue;
+				
+						default: 
+							/* i.e. more dirt */
+							if (pos - start < fmc->max_chunk_size) {
+								/* There wasn't much before the dirt
+								   started again. Just mark it all dirty
+								*/
+								goto cont_dirty;
+							}
+							/* There was quite a lot of free space. Leave it
+							   free.
+							*/
+							goto cont_scan;
+						}
+					}
 				default:
 					break;
 				}


--
dwmw2