mtd/fs/jffs3 erase.c, 3.9, 3.10 gc.c, 3.11, 3.12 os-linux.h, 3.5, 3.6 scan.c, 3.13, 3.14 scan.h, 1.6, 1.7 wbuf.c, 3.15, 3.16

Andrew Victor pavlov at infradead.org
Wed Feb 9 09:52:08 EST 2005


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

Modified Files:
	erase.c gc.c os-linux.h scan.c scan.h wbuf.c 
Log Message:
Core changes required to support JFFS3-on-Dataflash devices.

DataFlash page-sizes are not a power of two (they're multiples of 528
bytes).  There are a few places in JFFS3 code where sector_size is used
as a bitmask.  A new macro (SECTOR_ADDR) was defined to calculate these
sector addresses. For non-DataFlash devices, the original (faster)
bitmask operation is still used.

In scan.c, the EMPTY_SCAN_SIZE was a constant of 1024. 
Since this could be larger than the sector size of the DataFlash, this
is now basically set to MIN(sector_size, 1024).

Addition of a jffs3_is_writebuffered() macro.

(This is now the same as JFFS2)


Signed-off-by: Andrew Victor <andrew at sanpeople.com>



Index: erase.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/erase.c,v
retrieving revision 3.9
retrieving revision 3.10
diff -u -r3.9 -r3.10
--- erase.c	5 Feb 2005 18:21:55 -0000	3.9
+++ erase.c	9 Feb 2005 14:52:05 -0000	3.10
@@ -238,7 +238,7 @@
 			continue;
 		}
 
-		if (((*prev)->flash_offset & ~(c->sector_size -1)) == jeb->offset) {
+		if (SECTOR_ADDR((*prev)->flash_offset) == jeb->offset) {
 			/* It's in the block we're erasing */
 			struct jffs3_raw_node_ref *this;
 

Index: gc.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/gc.c,v
retrieving revision 3.11
retrieving revision 3.12
diff -u -r3.11 -r3.12
--- gc.c	21 Jan 2005 10:55:42 -0000	3.11
+++ gc.c	9 Feb 2005 14:52:05 -0000	3.12
@@ -831,8 +831,7 @@
 
 			/* Doesn't matter if there's one in the same erase block. We're going to
 			   delete it too at the same time. */
-			if ((raw->flash_offset & ~(c->sector_size-1)) ==
-			    (fd->raw->flash_offset & ~(c->sector_size-1)))
+			if (SECTOR_ADDR(raw->flash_offset) == SECTOR_ADDR(fd->raw->flash_offset))
 				continue;
 
 			DBG_GC(1, "Check potential deletion dirent at %#08x\n", ref_offset(raw));

Index: os-linux.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/os-linux.h,v
retrieving revision 3.5
retrieving revision 3.6
diff -u -r3.5 -r3.6
--- os-linux.h	9 Feb 2005 14:25:15 -0000	3.5
+++ os-linux.h	9 Feb 2005 14:52:05 -0000	3.6
@@ -98,7 +98,10 @@
 #endif
 }
 
+#define SECTOR_ADDR(x) ( ((unsigned long)(x) & ~(c->sector_size-1)) )
+
 #define jffs3_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
+#define jffs3_is_writebuffered(c) (c->wbuf != NULL)
 
 #ifndef CONFIG_JFFS3_FS_WRITEBUFFER
 #ifndef CONFIG_JFFS3_SUMMARY

Index: scan.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/scan.c,v
retrieving revision 3.13
retrieving revision 3.14
diff -u -r3.13 -r3.14
--- scan.c	9 Feb 2005 14:25:15 -0000	3.13
+++ scan.c	9 Feb 2005 14:52:05 -0000	3.14
@@ -344,7 +344,7 @@
 #endif
 
 	} else {
-		buf_len = EMPTY_SCAN_SIZE;
+		buf_len = EMPTY_SCAN_SIZE(c->sector_size);
 		err = jffs3_fill_scan_buf(c, buf, buf_ofs, buf_len);
 		if (err)
 			return err;
@@ -354,10 +354,10 @@
 	ofs = 0;
 
 	/* Scan only 4KiB of 0xFF before declaring it's empty */
-	while(ofs < EMPTY_SCAN_SIZE && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF)
+	while(ofs < EMPTY_SCAN_SIZE(c->sector_size) && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF)
 		ofs += 4;
 
-	if (ofs == EMPTY_SCAN_SIZE) {
+	if (ofs == EMPTY_SCAN_SIZE(c->sector_size)) {
 #ifdef CONFIG_JFFS3_FS_WRITEBUFFER
 		if (jffs3_cleanmarker_oob(c)) {
 			/* scan oob, take care of cleanmarker */
@@ -466,7 +466,7 @@
 			if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) &&
 			    c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_in_ino) {
 				DBG_SCAN(1, "%d bytes at start of block seems clean... "
-						"assuming all clean\n", EMPTY_SCAN_SIZE);
+						"assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size));
 				return BLK_STATE_CLEANMARKER;
 			}
 

Index: scan.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/scan.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- scan.h	5 Jan 2005 16:19:00 -0000	1.6
+++ scan.h	9 Feb 2005 14:52:05 -0000	1.7
@@ -42,7 +42,7 @@
 #define BLK_STATE_ALLDIRTY	4
 #define BLK_STATE_BADBLOCK	5
 
-#define EMPTY_SCAN_SIZE 1024
+#define DEFAULT_EMPTY_SCAN_SIZE 1024
 
 #define DBG_NOISY(noise, args...) do { \
 	if (*(noise)) { \
@@ -118,4 +118,11 @@
 		return 0;
 }
 
+static inline uint32_t EMPTY_SCAN_SIZE(uint32_t sector_size) {
+	if (sector_size < DEFAULT_EMPTY_SCAN_SIZE)
+		return sector_size;
+	else
+		return DEFAULT_EMPTY_SCAN_SIZE;
+}
+
 #endif /* __JFFS3_SCAN_H__ */

Index: wbuf.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/wbuf.c,v
retrieving revision 3.15
retrieving revision 3.16
diff -u -r3.15 -r3.16
--- wbuf.c	9 Feb 2005 14:25:15 -0000	3.15
+++ wbuf.c	9 Feb 2005 14:52:05 -0000	3.16
@@ -407,9 +407,9 @@
 	int ret;
 	size_t retlen;
 
-	/* Nothing to do if not NAND flash. In particular, we shouldn't
+	/* Nothing to do if not write-buffering the flash. In particular, we shouldn't
 	   del_timer() the timer we never initialised. */
-	if (jffs3_can_mark_obsolete(c))
+	if (!jffs3_is_writebuffered(c))
 		return 0;
 
 	DBG_WBUF(2, "pad %d, wbuf_ofs %#08x, wbuf_len %#x, to pad %#x\n", pad,
@@ -425,7 +425,7 @@
 		down(&c->alloc_sem);
 	}
 
-	if(!c->wbuf || !c->wbuf_len)
+	if (!c->wbuf_len)	/* already checked c->wbuf above */
 		return 0;
 
 	/* claim remaining space on the page
@@ -602,7 +602,7 @@
 	uint32_t outvec_to = to;
 
 	/* If not NAND flash, don't bother */
-	if (!c->wbuf){
+	if (!jffs3_is_writebuffered(c)) {
 		return jffs3_flash_direct_writev(c, invecs, count, to, retlen);
 	}
 
@@ -632,7 +632,7 @@
 	   erase block. Anything else, and you die.
 	   New block starts at xxx000c (0-b = block header)
 	*/
-	if ( (to & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) {
+	if (SECTOR_ADDR(to) != SECTOR_ADDR(c->wbuf_ofs)) {
 		/* It's a write to a new block */
 		if (c->wbuf_len) {
 			DBG_WBUF(1, "writev to 0x%lx causes flush of wbuf at 0x%08x\n", (unsigned long)to, c->wbuf_ofs);
@@ -837,7 +837,7 @@
 {
 	struct kvec vecs[1];
 
-	if (jffs3_can_mark_obsolete(c))
+	if (!jffs3_is_writebuffered(c))
 		return c->mtd->write(c->mtd, ofs, len, retlen, buf);
 
 	vecs[0].iov_base = (unsigned char *) buf;
@@ -853,37 +853,36 @@
 	loff_t	orbf = 0, owbf = 0, lwbf = 0;
 	int	ret;
 
-	/* Read flash */
-	if (!jffs3_can_mark_obsolete(c)) {
+	if (!jffs3_is_writebuffered(c))
+		return c->mtd->read(c->mtd, ofs, len, retlen, buf);
 
-		if (jffs3_cleanmarker_oob(c))
-			ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
-		else
-			ret = c->mtd->read(c->mtd, ofs, len, retlen, buf);
+	/* Read flash */
+	if (jffs3_cleanmarker_oob(c))
+		ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
+	else
+		ret = c->mtd->read(c->mtd, ofs, len, retlen, buf);
 
-		if ( (ret == -EBADMSG) && (*retlen == len) ) {
-			WARNING_MSG("mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n", len, ofs);
-			/*
-			 * We have the raw data without ECC correction in the buffer, maybe
-			 * we are lucky and all data or parts are correct. We check the node.
-			 * If data are corrupted node check will sort it out.
-			 * We keep this block, it will fail on write or erase and the we
-			 * mark it bad. Or should we do that now? But we should give him a chance.
-			 * Maybe we had a system crash or power loss before the ecc write or
-			 * a erase was completed.
-			 * So we return success. :)
-			 */
-		 	ret = 0;
-		 }
-	} else
-		return c->mtd->read(c->mtd, ofs, len, retlen, buf);
+	if ( (ret == -EBADMSG) && (*retlen == len) ) {
+		WARNING_MSG("mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n", len, ofs);
+		/*
+		 * We have the raw data without ECC correction in the buffer, maybe
+		 * we are lucky and all data or parts are correct. We check the node.
+		 * If data are corrupted node check will sort it out.
+		 * We keep this block, it will fail on write or erase and the we
+		 * mark it bad. Or should we do that now? But we should give him a chance.
+		 * Maybe we had a system crash or power loss before the ecc write or
+		 * a erase was completed.
+		 * So we return success. :)
+		 */
+	 	ret = 0;
+	 }
 
 	/* if no writebuffer available or write buffer empty, return */
 	if (!c->wbuf_pagesize || !c->wbuf_len)
 		return ret;
 
 	/* if we read in a different block, return */
-	if ( (ofs & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) )
+	if (SECTOR_ADDR(ofs) != SECTOR_ADDR(c->wbuf_ofs))
 		return ret;
 
 	/* Lock only if we have reason to believe wbuf contains relevant data,





More information about the linux-mtd-cvs mailing list