mtd/fs/jffs2 wbuf.c,1.20,1.21

gleixner at infradead.org gleixner at infradead.org
Sun Nov 24 16:08:49 EST 2002


Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv32002

Modified Files:
	wbuf.c 
Log Message:
support virtual blocks of 2/4/8 physical blocks

Index: wbuf.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/wbuf.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- wbuf.c	12 Nov 2002 11:33:02 -0000	1.20
+++ wbuf.c	24 Nov 2002 21:08:45 -0000	1.21
@@ -578,69 +578,83 @@
 	return ret;
 }
 
-int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
+/*
+*	Scan for a valid cleanmarker and for bad blocks
+*	For virtual blocks (concatenated physical blocks) check the cleanmarker
+*	only in the first page of the first physical block, but scan for bad blocks in all
+*	physical blocks
+*/
+int jffs2_check_nand_cleanmarker (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
 {
 	struct jffs2_unknown_node n;
 	unsigned char buf[32];
 	unsigned char *p;
-	int ret,i;
-	size_t retlen;
-	int	fsdata_pos,fsdata_len, oob_size, badblock_pos;
+	int ret, i, cnt, retval = 0;
+	size_t retlen, offset;
+	int fsdata_pos, fsdata_len, oob_size, badblock_pos;
 
+	offset = jeb->offset;
 	oob_size = c->mtd->oobsize;
 
-	switch(c->mtd->ecctype) {
-	case MTD_ECC_SW:	
+	switch (c->mtd->ecctype) {
+	case MTD_ECC_SW:
 		fsdata_pos = (c->wbuf_pagesize == 256) ? NAND_JFFS2_OOB8_FSDAPOS : NAND_JFFS2_OOB16_FSDAPOS;
 		fsdata_len = (c->wbuf_pagesize == 256) ? NAND_JFFS2_OOB8_FSDALEN : NAND_JFFS2_OOB16_FSDALEN;
 		badblock_pos = NAND_BADBLOCK_POS;
 		break;
 	default:
-		D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Invalid ECC type\n"));
+		D1 (printk (KERN_WARNING "jffs2_write_nand_cleanmarker(): Invalid ECC type\n"));
 		return -EINVAL;
-	}	
-
-	/*
-	*	We read oob data from page 0 and 1 of the block.
-	*	page 0 contains cleanmarker and badblock info
-	*	page 2 contains failure count of this block
-	*/
-	ret = c->mtd->read_oob(c->mtd, jeb->offset, oob_size << 1 , &retlen, buf);
-	
-	if (ret) {
-		D1(printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
-		return ret;
-	}
-	if (retlen < (oob_size << 1) ) {
-		D1(printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB return short read (%d bytes not %d) for block at %08x\n", retlen, oob_size << 1 , jeb->offset));
-		return -EIO;
 	}
 
-	/* Check for bad block marker */
-	if (buf[badblock_pos] != 0xff) {
-		D1(printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Bad block at %08x\n",jeb->offset));
-		return 2;
-	}
 
-	/* Check for failure counter in the second page */
-	if (buf[badblock_pos+oob_size] != 0xff) {
-		D1(printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Block marked as failed at %08x, fail count:%d\n",jeb->offset,buf[badblock_pos+oob_size]));
-		return 3;
-	}
+	/* Loop through the physical blocks */
+	for (cnt = 0; cnt < (c->sector_size / c->mtd->erasesize); cnt++) {
+		/*
+		   *    We read oob data from page 0 and 1 of the block.
+		   *    page 0 contains cleanmarker and badblock info
+		   *    page 1 contains failure count of this block
+		 */
+		ret = c->mtd->read_oob (c->mtd, offset, oob_size << 1, &retlen, buf);
+
+		if (ret) {
+			D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
+			return ret;
+		}
+		if (retlen < (oob_size << 1)) {
+			D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB return short read (%d bytes not %d) for block at %08x\n", retlen, oob_size << 1, jeb->offset));
+			return -EIO;
+		}
+
+		/* Check for bad block marker */
+		if (buf[badblock_pos] != 0xff) {
+			D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Bad block at %08x\n", jeb->offset));
+			return 2;
+		}
+
+		/* Check for failure counter in the second page */
+		if (buf[badblock_pos + oob_size] != 0xff) {
+			D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Block marked as failed at %08x, fail count:%d\n", jeb->offset, buf[badblock_pos + oob_size]));
+			return 3;
+		}
 
-	n.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-	n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
-	n.totlen = cpu_to_je32(8);
-	p = (unsigned char *) &n;
-	
-	for (i = 0; i < fsdata_len; i++) {
-		if (buf[fsdata_pos+i] != p[i]) {
-			D2(printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Cleanmarker node not detected in block at %08x\n", jeb->offset));
-			return 1;
+		/* Check cleanmarker only on the first physical block */
+		if (!cnt) {
+			n.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK);
+			n.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER);
+			n.totlen = cpu_to_je32 (8);
+			p = (unsigned char *) &n;
+
+			for (i = 0; i < fsdata_len; i++) {
+				if (buf[fsdata_pos + i] != p[i]) {
+					D2 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Cleanmarker node not detected in block at %08x\n", jeb->offset));
+					retval = 1;
+				}
+			}
 		}
+		offset += c->mtd->erasesize;
 	}
-	
-	return 0;
+	return retval;
 }
 
 int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)





More information about the linux-mtd-cvs mailing list