[U-Boot-Users] JFFS2 speed enhancement patch

Christian Hohnstaedt chohnstaedt at innominate.com
Fri Apr 23 15:52:33 CEST 2004


Hi,

for the sake of speed I repaired the header CRC calculation
in the jffs2_1pass.c.

I also added the eraseblock size to the partition information
to skip empty eraseblocks if we find more then 4k of free space.

The JFFS2 scanner is now fast enough to remove the spinning
wheel so I #ifdef-ed it out.

I added watchdog calls in the long running loops.

The speed increasement was x10 on my board.
I tested this for some days now and it works good for me.


regards
Christian

-- 
Christian Hohnstaedt                   Innominate Security Technologies AG
software engineer                      networking people
tel: +49.30.6392-3308                  http://www.innominate.com
-------------- next part --------------
Index: common/cmd_jffs2.c
===================================================================
RCS file: /cvsroot/u-boot/u-boot/common/cmd_jffs2.c,v
retrieving revision 1.9
diff -u -r1.9 cmd_jffs2.c
--- common/cmd_jffs2.c	18 Apr 2004 19:43:39 -0000	1.9
+++ common/cmd_jffs2.c	23 Apr 2004 13:53:24 -0000
@@ -80,8 +80,14 @@
 			flash_info[CFG_JFFS2_FIRST_BANK].start[0];
 #endif
 
-		/* unused in current jffs2 loader */
-		part.erasesize = 0;
+		/* FIXME: Fast hack to get erase size set */
+
+		/* We assume that our JFFS2 partition has 
+		 * all erase blocks with the same size 
+		 * If we have a clue about the erasesize
+		 * we can skip empty blocks
+		 */
+		part.erasesize = PHYS_FLASH_SECT_SIZE;
 
 		/* Mark the struct as ready */
 		part.usr_priv=(void*)1;
Index: fs/jffs2/jffs2_1pass.c
===================================================================
RCS file: /cvsroot/u-boot/u-boot/fs/jffs2/jffs2_1pass.c,v
retrieving revision 1.10
diff -u -r1.10 jffs2_1pass.c
--- fs/jffs2/jffs2_1pass.c	18 Apr 2004 21:13:44 -0000	1.10
+++ fs/jffs2/jffs2_1pass.c	23 Apr 2004 13:53:24 -0000
@@ -114,6 +114,7 @@
 #include <common.h>
 #include <config.h>
 #include <malloc.h>
+#include <watchdog.h>
 #include <linux/stat.h>
 #include <linux/time.h>
 
@@ -126,7 +127,7 @@
 
 
 #define	NODE_CHUNK  	1024	/* size of memory allocation chunk in b_nodes */
-#define	SPIN_BLKSIZE	18  	/* spin after having scanned 1<<BLKSIZE bytes */
+#define	SPIN_BLKSIZE	20  	/* spin after having scanned 1<<BLKSIZE bytes */
 
 /* Debugging switches */
 #undef	DEBUG_DIRENTS		/* print directory entry list after scan */
@@ -276,8 +277,10 @@
 	"ZLIB"
 };
 
+#ifdef SPINNER
 /* Spinning wheel */
 static char spinner[] = { '|', '/', '-', '\\' };
+#endif
 
 /* Memory management */
 struct mem_block {
@@ -454,15 +457,24 @@
 {
 	char *max = part->offset + part->size - sizeof(struct jffs2_raw_inode);
 	char *offset = part->offset + start_offset;
+	int cntr = 0;
 	u32 off;
 
 	while (offset < max &&
 	       *(u32*)get_fl_mem((u32)offset, sizeof(u32), &off) == 0xFFFFFFFF) {
 		offset += sizeof(u32);
+		cntr++;
+#ifdef SPINNER
 		/* return if spinning is due */
 		if (((u32)offset & ((1 << SPIN_BLKSIZE)-1)) == 0) break;
+#endif
+		if (cntr > 1024 && part->erasesize > 0) { /* 4k */
+			/* round up to next erase block border */
+			(u32)offset |= part->erasesize-1;
+			offset++;
+			cntr = 0;
+		}
 	}
-
 	return offset - part->offset;
 }
 
@@ -921,6 +933,9 @@
 		for (i = 0; i < strlen(c) - 1; i++)
 			tmp[i] = c[i + 1];
 		tmp[i] = '\0';
+		
+		WATCHDOG_RESET();
+		
 		/* only a failure if we arent looking at top level */
 		if (!(pino = jffs2_1pass_find_inode(pL, working_tmp, pino)) &&
 		    (working_tmp[0])) {
@@ -1061,12 +1076,15 @@
 {
 	struct b_lists *pL;
 	struct jffs2_unknown_node *node;
+	struct jffs2_unknown_node crcnode;
 	u32 offset, oldoffset = 0;
 	u32 max = part->size - sizeof(struct jffs2_raw_inode);
 	u32 counter = 0;
 	u32 counter4 = 0;
 	u32 counterF = 0;
 	u32 counterN = 0;
+	u32 counterCRC = 0;
+	u32 counterUNK = 0;
 
 #if defined(CONFIG_JFFS2_NAND) && (CONFIG_COMMANDS & CFG_CMD_NAND)
 	nanddev = (int)part->usr_priv - 1;
@@ -1087,14 +1105,26 @@
 	/* start at the beginning of the partition */
 	while (offset < max) {
 	    	if ((oldoffset >> SPIN_BLKSIZE) != (offset >> SPIN_BLKSIZE)) {
+			WATCHDOG_RESET();
+#ifdef SPINNER
 			printf("\b\b%c ", spinner[counter++ % sizeof(spinner)]);
+#endif
 			oldoffset = offset;
 		}
-
 		node = (struct jffs2_unknown_node *) get_node_mem((u32)part->offset + offset);
-		if (node->magic == JFFS2_MAGIC_BITMASK && hdr_crc(node)) {
+		if (node->magic == JFFS2_MAGIC_BITMASK) {
 			/* if its a fragment add it */
-			if (node->nodetype == JFFS2_NODETYPE_INODE &&
+			/* check crc by readding a JFFS2_NODE_ACCURATE */
+			crcnode.magic = node->magic;
+			crcnode.nodetype = node->nodetype | JFFS2_NODE_ACCURATE;
+			crcnode.totlen = node->totlen;
+			crcnode.hdr_crc = node->hdr_crc;
+							      
+			if (!hdr_crc(&crcnode)) {
+				offset += 4;
+				counterCRC++;
+				continue;
+			} else if (node->nodetype == JFFS2_NODETYPE_INODE &&
 				    inode_crc((struct jffs2_raw_inode *) node)) {
 				if (insert_node(&pL->frag, (u32) part->offset +
 						offset) == NULL) {
@@ -1104,8 +1134,12 @@
 			} else if (node->nodetype == JFFS2_NODETYPE_DIRENT &&
 				   dirent_crc((struct jffs2_raw_dirent *) node)  &&
 				   dirent_name_crc((struct jffs2_raw_dirent *) node)) {
-				if (! (counterN%100))
+				if (! (counterN%128))
+#ifdef SPINNER
 					puts ("\b\b.  ");
+#else
+					puts (".");
+#endif
 				if (insert_node(&pL->dir, (u32) part->offset +
 						offset) == NULL) {
 					put_fl_mem(node);
@@ -1123,17 +1157,15 @@
 						"%d < %d\n", node->totlen,
 						sizeof(struct jffs2_unknown_node));
 			} else {
-				printf("Unknown node type: %x len %d "
-					"offset 0x%x\n", node->nodetype,
-					node->totlen, offset);
+				counterUNK++;
 			}
 			offset += ((node->totlen + 3) & ~3);
 			counterF++;
 		} else if (node->magic == JFFS2_EMPTY_BITMASK &&
 			   node->nodetype == JFFS2_EMPTY_BITMASK) {
 			offset = jffs2_scan_empty(offset, part);
-		} else {	/* if we know nothing, we just step and look. */
-			offset += 4;
+		} else { /* if we know nothing, we just step and look. */
+			offset += 4; 
 			counter4++;
 		}
 /*             printf("unknown node magic %4.4x %4.4x @ %lx\n", node->magic, node->nodetype, (unsigned long)node); */
@@ -1149,6 +1181,8 @@
 	putLabeledWord("frag entries = ", pL->frag.listCount);
 	putLabeledWord("+4 increments = ", counter4);
 	putLabeledWord("+file_offset increments = ", counterF);
+	putLabeledWord("Unknown node types = ", counterUNK);
+	putLabeledWord("Bad hdr_crc = ", counterCRC);
 
 #endif
 
@@ -1204,6 +1238,7 @@
 			return NULL;
 		}
 	}
+	WATCHDOG_RESET();
 	return (struct b_lists *)part->jffs2_priv;
 }
 
@@ -1213,24 +1248,21 @@
 jffs2_1pass_ls(struct part_info * part, const char *fname)
 {
 	struct b_lists *pl;
-	long ret = 0;
 	u32 inode;
 
 	if (! (pl = jffs2_get_list(part, "ls")))
 		return 0;
-
+	
+	
 	if (! (inode = jffs2_1pass_search_list_inodes(pl, fname, 1))) {
 		putstr("ls: Failed to scan jffs2 file structure\r\n");
 		return 0;
 	}
-
-
 #if 0
 	putLabeledWord("found file at inode = ", inode);
 	putLabeledWord("read_inode returns = ", ret);
 #endif
-
-	return ret;
+	return inode;
 }
 
 


More information about the U-Boot mailing list