diff packages/fs/jffs2/current/src/scan.c @ 1562:8bafb5f8a697

Merge changes from MTD - fix file truncate issue
author gthomas
date Thu, 01 Apr 2004 03:17:55 +0000
parents 121121d3d18f
children 0492a413d138
line wrap: on
line diff
--- a/packages/fs/jffs2/current/src/scan.c
+++ b/packages/fs/jffs2/current/src/scan.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: scan.c,v 1.106 2003/10/28 17:01:13 dwmw2 Exp $
+ * $Id: scan.c,v 1.109 2004/03/19 16:40:50 dwmw2 Exp $
  *
  */
 #include <linux/kernel.h>
@@ -285,8 +285,6 @@ static int jffs2_scan_eraseblock (struct
 	uint32_t hdr_crc, buf_ofs, buf_len;
 	int err;
 	int noise = 0;
-	int wasempty = 0;
-	uint32_t empty_start = 0;
 #ifdef CONFIG_JFFS2_FS_NAND
 	int cleanmarkerfound = 0;
 #endif
@@ -359,6 +357,7 @@ static int jffs2_scan_eraseblock (struct
 
 	noise = 10;
 
+scan_more:	
 	while(ofs < jeb->offset + c->sector_size) {
 
 		D1(ACCT_PARANOIA_CHECK(jeb));
@@ -398,42 +397,52 @@ static int jffs2_scan_eraseblock (struct
 		node = (struct jffs2_unknown_node *)&buf[ofs-buf_ofs];
 
 		if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) {
-			uint32_t inbuf_ofs = ofs - buf_ofs + 4;
-			uint32_t scanend;
+			uint32_t inbuf_ofs;
+			uint32_t empty_start;
 
 			empty_start = ofs;
 			ofs += 4;
 
-			/* If scanning empty space after only a cleanmarker, don't
-			   bother scanning the whole block */
-			if (unlikely(empty_start == jeb->offset + c->cleanmarker_size &&
-				     jeb->offset + EMPTY_SCAN_SIZE < buf_ofs + buf_len))
-				scanend = jeb->offset + EMPTY_SCAN_SIZE - buf_ofs;
-			else
-				scanend = buf_len;
-
 			D1(printk(KERN_DEBUG "Found empty flash at 0x%08x\n", ofs));
-			while (inbuf_ofs < scanend) {
-				if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff)
-					goto emptyends;
+		more_empty:
+			inbuf_ofs = ofs - buf_ofs;
+			while (inbuf_ofs < buf_len) {
+				if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff) {
+					printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n",
+					       empty_start, ofs);
+					DIRTY_SPACE(ofs-empty_start);
+					goto scan_more;
+				}
 
 				inbuf_ofs+=4;
 				ofs += 4;
 			}
 			/* Ran off end. */
-			D1(printk(KERN_DEBUG "Empty flash ends normally at 0x%08x\n", ofs));
+			D1(printk(KERN_DEBUG "Empty flash to end of buffer at 0x%08x\n", ofs));
 
-			if (buf_ofs == jeb->offset &&  jeb->used_size == PAD(c->cleanmarker_size) && 
-			    c->cleanmarker_size && !jeb->first_node->next_in_ino && !jeb->dirty_size)
+			/* If we're only checking the beginning of a block with a cleanmarker,
+			   bail now */
+			if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && 
+			    c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_in_ino) {
+				D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE));
 				return BLK_STATE_CLEANMARKER;
-			wasempty = 1;
-			continue;
-		} else if (wasempty) {
-		emptyends:
-			printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n", empty_start, ofs);
-			DIRTY_SPACE(ofs-empty_start);
-			wasempty = 0;
-			continue;
+			}
+
+			/* See how much more there is to read in this eraseblock... */
+			buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
+			if (!buf_len) {
+				/* No more to read. Break out of main loop without marking 
+				   this range of empty space as dirty (because it's not) */
+				D1(printk(KERN_DEBUG "Empty flash at %08x runs to end of block. Treating as free_space\n",
+					  empty_start));
+				break;
+			}
+			D1(printk(KERN_DEBUG "Reading another 0x%x at 0x%08x\n", buf_len, ofs));
+			err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
+			if (err)
+				return err;
+			buf_ofs = ofs;
+			goto more_empty;
 		}
 
 		if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) {
@@ -610,7 +619,7 @@ static int jffs2_scan_eraseblock (struct
 	}
 
 	if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size 
-		&& (!jeb->first_node || jeb->first_node->next_in_ino) )
+		&& (!jeb->first_node || !jeb->first_node->next_in_ino) )
 		return BLK_STATE_CLEANMARKER;
 		
 	/* move blocks with max 4 byte dirty space to cleanlist */