mtd/fs/jffs3 background.c, 3.6, 3.7 build.c, 3.6, 3.7 compr.c, 3.4, 3.5 compr.h, 3.3, 3.4 compr_lzari.c, 3.1, 3.2 compr_lzo.c, 3.1, 3.2 compr_rtime.c, 3.3, 3.4 compr_rubin.c, 3.3, 3.4 compr_rubin.h, 3.1, 3.2 compr_zlib.c, 3.3, 3.4 crc32.h, 3.1, 3.2 debug.c, 1.7, 1.8 debug.h, 1.18, 1.19 dir.c, 3.5, 3.6 erase.c, 3.5, 3.6 file.c, 3.5, 3.6 fs.c, 3.6, 3.7 gc.c, 3.8, 3.9 histo.h, 3.1, 3.2 histo_mips.h, 3.1, 3.2 ioctl.c, 3.1, 3.2 jffs3.h, 3.4, 3.5 malloc.c, 3.4, 3.5 nodelist.c, 3.3, 3.4 nodelist.h, 3.7, 3.8 nodemgmt.c, 3.6, 3.7 os-linux.h, 3.2, 3.3 rbtree.c, 3.1, 3.2 read.c, 3.5, 3.6 readinode.c, 3.5, 3.6 scan.c, 3.6, 3.7 summary.c, 3.2, 3.3 summary.h, 3.1, 3.2 super-v24.c, 3.3, 3.4 super.c, 3.5, 3.6 symlink-v24.c, 3.1, 3.2 symlink.c, 3.1, 3.2 wbuf.c, 3.7, 3.8 write.c, 3.7, 3.8

Artem Bityuckiy dedekind at infradead.org
Sat Dec 25 06:11:25 EST 2004


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

Modified Files:
	background.c build.c compr.c compr.h compr_lzari.c compr_lzo.c 
	compr_rtime.c compr_rubin.c compr_rubin.h compr_zlib.c crc32.h 
	debug.c debug.h dir.c erase.c file.c fs.c gc.c histo.h 
	histo_mips.h ioctl.c jffs3.h malloc.c nodelist.c nodelist.h 
	nodemgmt.c os-linux.h rbtree.c read.c readinode.c scan.c 
	summary.c summary.h super-v24.c super.c symlink-v24.c 
	symlink.c wbuf.c write.c 
Log Message:
1. Complete __totlen elimination. Tested on NAND without summary. Works
   well.
2. Some formating tweaks.
3. Summary is broken :-(
4. Some tweaks with the debug stuff.
5. Did not tested on NOR yet.


Index: background.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/background.c,v
retrieving revision 3.6
retrieving revision 3.7
diff -u -r3.6 -r3.7
--- background.c	22 Dec 2004 18:37:23 -0000	3.6
+++ background.c	25 Dec 2004 11:11:20 -0000	3.7
@@ -52,7 +52,7 @@
 		DBG_GCT(1, "Garbage collect thread is pid %d\n", pid);
 		down(&c->gc_thread_start);
 	}
- 
+
 	return ret;
 }
 
@@ -103,7 +103,7 @@
 
 		cond_resched();
 
-		/* Put_super will send a SIGKILL and then wait on the sem. 
+		/* Put_super will send a SIGKILL and then wait on the sem.
 		 */
 		while (signal_pending(current)) {
 			siginfo_t info;

Index: build.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/build.c,v
retrieving revision 3.6
retrieving revision 3.7
diff -u -r3.6 -r3.7
--- build.c	23 Dec 2004 18:53:36 -0000	3.6
+++ build.c	25 Dec 2004 11:11:20 -0000	3.7
@@ -136,10 +136,10 @@
 				ic->ino, ic->nlink, ic, ic->nodes);
 		if (ic->nlink)
 			continue;
-			
+
 		jffs3_build_remove_unlinked_inode(c, ic, &dead_fds);
 		cond_resched();
-	} 
+	}
 
 	DBG_BLD(1, "Pass 2a starting\n");
 
@@ -156,7 +156,7 @@
 	}
 
 	DBG_BLD(1, "Pass 2 complete\n");
-	
+
 	/* Finally, we can scan again and free the dirent structs */
 	for_each_inode(i, c, ic) {
 		DBG_BLD(1, "Pass 3: ino #%u, ic %p, nodes %p\n", ic->ino, ic, ic->nodes);
@@ -200,7 +200,7 @@
 	struct jffs3_full_dirent *fd;
 
 	DBG_BLD(1, "Removing ino #%u with nlink == zero.\n", ic->ino);
-	
+
 	raw = ic->nodes;
 	while (raw != (void *)ic) {
 		struct jffs3_raw_node_ref *next = raw->next_in_ino;
@@ -232,7 +232,7 @@
 			}
 
 			DBG_BLD(1, "Removing child \"%s\", ino #%u\n", fd->name, fd->ino);
-			
+
 			child_ic = jffs3_get_ino_cache(c, fd->ino);
 			if (!child_ic) {
 				NOTICE_MSG("Cannot remove child \"%s\", ino #%u, "
@@ -241,11 +241,11 @@
 				continue;
 			}
 
-			/* Reduce nlink of the child. If it's now zero, stick it on the 
+			/* Reduce nlink of the child. If it's now zero, stick it on the
 			   dead_fds list to be cleaned up later. Else just free the fd */
 
 			child_ic->nlink--;
-			
+
 			if (!child_ic->nlink) {
 				DBG_BLD(1, "Inode #%u (\"%s\") has now got zero nlink. Adding to dead_fds list.\n",
 					  fd->ino, fd->name);
@@ -260,7 +260,7 @@
 	}
 
 	/*
-	   We don't delete the inocache from the hash list and free it yet. 
+	   We don't delete the inocache from the hash list and free it yet.
 	   The erase code will do that, when all the nodes are completely gone.
 	*/
 }
@@ -274,7 +274,7 @@
 	   because there's not enough free space... */
 	c->resv_blocks_deletion = 2;
 
-	/* Be conservative about how much space we need before we allow writes. 
+	/* Be conservative about how much space we need before we allow writes.
 	   On top of that which is required for deletia, require an extra 2%
 	   of the medium to be available, for overhead caused by nodes being
 	   split across blocks, etc. */
@@ -289,7 +289,7 @@
 
 	c->resv_blocks_gctrigger = c->resv_blocks_write + 1;
 
-	/* When do we allow garbage collection to merge nodes to make 
+	/* When do we allow garbage collection to merge nodes to make
 	   long-term progress at the expense of short-term space exhaustion? */
 	c->resv_blocks_gcmerge = c->resv_blocks_deletion + 1;
 
@@ -315,7 +315,7 @@
 		  c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024);
 	DBG_BLD(1, "Amount of dirty space required to GC: %d bytes\n",
 		  c->nospc_dirty_size);
-} 
+}
 
 int jffs3_do_mount_fs(struct jffs3_sb_info *c)
 {
@@ -340,7 +340,7 @@
 		c->blocks[i].first_node = NULL;
 		c->blocks[i].last_node = NULL;
 		c->blocks[i].bad_count = 0;
-#ifdef CONFIG_JFFS3_SUMMARY	
+#ifdef CONFIG_JFFS3_SUMMARY
  		c->blocks[i].sum_collected = NULL;
 #endif
 	}

Index: compr.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/compr.c,v
retrieving revision 3.4
retrieving revision 3.5
diff -u -r3.4 -r3.5
--- compr.c	23 Dec 2004 18:53:36 -0000	3.4
+++ compr.c	25 Dec 2004 11:11:20 -0000	3.5
@@ -25,7 +25,7 @@
 /* Actual compression mode */
 static int jffs3_compression_mode = JFFS3_COMPR_MODE_PRIORITY;
 
-void jffs3_set_compression_mode(int mode) 
+void jffs3_set_compression_mode(int mode)
 {
         jffs3_compression_mode = mode;
 }
@@ -48,16 +48,16 @@
  *	data.
  *
  * Returns: Lower byte to be stored with data indicating compression type used.
- * Zero is used to show that the data could not be compressed - the 
+ * Zero is used to show that the data could not be compressed - the
  * compressed version was actually larger than the original.
  * Upper byte will be used later. (soon)
  *
  * If the cdata buffer isn't large enough to hold all the uncompressed data,
- * jffs3_compress should compress as much as will fit, and should set 
+ * jffs3_compress should compress as much as will fit, and should set
  * *datalen accordingly to show the amount of data which were compressed.
  */
 uint16_t jffs3_compress(struct jffs3_sb_info *c, struct jffs3_inode_info *f,
-			     unsigned char *data_in, unsigned char **cpage_out, 
+			     unsigned char *data_in, unsigned char **cpage_out,
 			     uint32_t *datalen, uint32_t *cdatalen)
 {
 	int ret = JFFS3_COMPR_NONE;
@@ -176,7 +176,7 @@
 }
 
 int jffs3_decompress(struct jffs3_sb_info *c, struct jffs3_inode_info *f,
-		     uint16_t comprtype, unsigned char *cdata_in, 
+		     uint16_t comprtype, unsigned char *cdata_in,
 		     unsigned char *data_out, uint32_t cdatalen, uint32_t datalen)
 {
         struct jffs3_compressor *this;
@@ -311,7 +311,7 @@
 
         act_buf += sprintf(act_buf,"JFFS3 compressor statistics:\n");
         act_buf += sprintf(act_buf,"%10s   ","none");
-        act_buf += sprintf(act_buf,"compr: %d blocks (%d)  decompr: %d blocks\n", none_stat_compr_blocks, 
+        act_buf += sprintf(act_buf,"compr: %d blocks (%d)  decompr: %d blocks\n", none_stat_compr_blocks,
                            none_stat_compr_size, none_stat_decompr_blocks);
         spin_lock(&jffs3_compressor_list_lock);
         list_for_each_entry(this, &jffs3_compressor_list, list) {
@@ -320,8 +320,8 @@
                         act_buf += sprintf(act_buf,"- ");
                 else
                         act_buf += sprintf(act_buf,"+ ");
-                act_buf += sprintf(act_buf,"compr: %d blocks (%d/%d)  decompr: %d blocks ", this->stat_compr_blocks, 
-                                   this->stat_compr_new_size, this->stat_compr_orig_size, 
+                act_buf += sprintf(act_buf,"compr: %d blocks (%d/%d)  decompr: %d blocks ", this->stat_compr_blocks,
+                                   this->stat_compr_new_size, this->stat_compr_orig_size,
                                    this->stat_decompr_blocks);
                 act_buf += sprintf(act_buf,"\n");
         }
@@ -330,7 +330,7 @@
         return buf;
 }
 
-char *jffs3_get_compression_mode_name(void) 
+char *jffs3_get_compression_mode_name(void)
 {
         switch (jffs3_compression_mode) {
         case JFFS3_COMPR_MODE_NONE:
@@ -343,7 +343,7 @@
         return "unkown";
 }
 
-int jffs3_set_compression_mode_name(const char *name) 
+int jffs3_set_compression_mode_name(const char *name)
 {
         if (!strcmp("none",name)) {
                 jffs3_compression_mode = JFFS3_COMPR_MODE_NONE;
@@ -368,7 +368,7 @@
                 if (!strcmp(this->name, name)) {
                         this->disabled = disabled;
                         spin_unlock(&jffs3_compressor_list_lock);
-                        return 0;                        
+                        return 0;
                 }
         }
         spin_unlock(&jffs3_compressor_list_lock);
@@ -398,7 +398,7 @@
                 }
         }
         spin_unlock(&jffs3_compressor_list_lock);
-        WARNING_MSG("Compressor %s not found.\n",name);        
+        WARNING_MSG("Compressor %s not found.\n",name);
         return 1;
 reinsert:
         /* list is sorted in the order of priority, so if
@@ -425,7 +425,7 @@
                 kfree(comprbuf);
 }
 
-int jffs3_compressors_init(void) 
+int jffs3_compressors_init(void)
 {
 /* Registering compressors */
 #ifdef CONFIG_JFFS3_ZLIB
@@ -459,7 +459,7 @@
         return 0;
 }
 
-int jffs3_compressors_exit(void) 
+int jffs3_compressors_exit(void)
 {
 /* Unregistering compressors */
 #ifdef CONFIG_JFFS3_LZO

Index: compr.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/compr.h,v
retrieving revision 3.3
retrieving revision 3.4
diff -u -r3.3 -r3.4
--- compr.h	13 Dec 2004 11:35:41 -0000	3.3
+++ compr.h	25 Dec 2004 11:11:20 -0000	3.4
@@ -4,7 +4,7 @@
  * Copyright (C) 2004 Ferenc Havasi <havasi at inf.u-szeged.hu>,
  *                    University of Szeged, Hungary
  *
- * For licensing information, see the file 'LICENCE' in the 
+ * For licensing information, see the file 'LICENCE' in the
  * jffs3 directory.
  *
  * JFFS2 Id: compr.h,v 1.6 2004/07/16 15:17:57 dwmw2  Exp

Index: compr_lzari.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/compr_lzari.c,v
retrieving revision 3.1
retrieving revision 3.2
diff -u -r3.1 -r3.2
--- compr_lzari.c	9 Dec 2004 16:05:03 -0000	3.1
+++ compr_lzari.c	25 Dec 2004 11:11:20 -0000	3.2
@@ -125,7 +125,7 @@
 static void DeleteNode(unsigned long p)  /* Delete node p from tree */
 {
 	unsigned long  q;
-	
+
 	if (dad[p] == NIL) return;  /* not in tree */
 	if (rson[p] == NIL) q = lson[p];
 	else if (lson[p] == NIL) q = rson[p];
@@ -174,7 +174,7 @@
 static void StartModel(void)  /* Initialize model */
 {
 	unsigned long ch, sym, i;
-	
+
 	sym_cum[N_CHAR] = 0;
 	for (sym = N_CHAR; sym >= 1; sym--) {
 		ch = sym - 1;
@@ -219,7 +219,7 @@
 	   i such that sym_cum[i - 1] > x >= sym_cum[i] otherwise */
 {
 	unsigned long i, j, k;
-	
+
 	i = 1;  j = N_CHAR;
 	while (i < j) {
 		k = (i + j) / 2;
@@ -234,7 +234,7 @@
 	   i such that position_cum[i] > x >= position_cum[i + 1] otherwise */
 {
 	unsigned long i, j, k;
-	
+
 	i = 1;  j = N;
 	while (i < j) {
 		k = (i + j) / 2;
@@ -661,7 +661,7 @@
 				*(op++) = c;
 				text_buf[r++] = c;
 				r &= (N - 1);
-			}		
+			}
 		}
 	}
 	return 0;

Index: compr_lzo.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/compr_lzo.c,v
retrieving revision 3.1
retrieving revision 3.2
diff -u -r3.1 -r3.2
--- compr_lzo.c	9 Dec 2004 16:05:03 -0000	3.1
+++ compr_lzo.c	25 Dec 2004 11:11:20 -0000	3.2
@@ -63,7 +63,7 @@
 					-all sensitive data will be on 4 byte boundary
 					-removed check parts for library use
 					-removed all but LZO1X-* compression
-					
+
 */
 
 #ifndef __KERNEL__

Index: compr_rtime.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/compr_rtime.c,v
retrieving revision 3.3
retrieving revision 3.4
diff -u -r3.3 -r3.4
--- compr_rtime.c	13 Dec 2004 11:35:41 -0000	3.3
+++ compr_rtime.c	25 Dec 2004 11:11:20 -0000	3.4
@@ -25,31 +25,31 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/errno.h>
-#include <linux/string.h> 
-#include "jffs3.h" 
+#include <linux/string.h>
+#include "jffs3.h"
 #include "compr.h"
 
 /* _compress returns the compressed size, -1 if bigger */
-int jffs3_rtime_compress(unsigned char *data_in, unsigned char *cpage_out, 
+int jffs3_rtime_compress(unsigned char *data_in, unsigned char *cpage_out,
 		   uint32_t *sourcelen, uint32_t *dstlen, void *model)
 {
 	short positions[256];
 	int outpos = 0;
 	int pos=0;
 
-	memset(positions,0,sizeof(positions)); 
-	
+	memset(positions,0,sizeof(positions));
+
 	while (pos < (*sourcelen) && outpos <= (*dstlen)-2) {
 		int backpos, runlen=0;
 		unsigned char value;
-		
+
 		value = data_in[pos];
 
 		cpage_out[outpos++] = data_in[pos++];
-		
+
 		backpos = positions[value];
 		positions[value]=pos;
-		
+
 		while ((backpos < pos) && (pos < (*sourcelen)) &&
 		       (data_in[pos]==data_in[backpos++]) && (runlen<255)) {
 			pos++;
@@ -62,12 +62,12 @@
 		/* We failed */
 		return -1;
 	}
-	
+
 	/* Tell the caller how much we managed to compress, and how much space it took */
 	*sourcelen = pos;
 	*dstlen = outpos;
 	return 0;
-}		   
+}
 
 
 int jffs3_rtime_decompress(unsigned char *data_in, unsigned char *cpage_out,
@@ -76,19 +76,19 @@
 	short positions[256];
 	int outpos = 0;
 	int pos=0;
-	
-	memset(positions,0,sizeof(positions)); 
-	
+
+	memset(positions,0,sizeof(positions));
+
 	while (outpos<destlen) {
 		unsigned char value;
 		int backoffs;
 		int repeat;
-		
+
 		value = data_in[pos++];
 		cpage_out[outpos++] = value; /* first the verbatim copied byte */
 		repeat = data_in[pos++];
 		backoffs = positions[value];
-		
+
 		positions[value]=outpos;
 		if (repeat) {
 			if (backoffs + repeat >= outpos) {
@@ -98,12 +98,12 @@
 				}
 			} else {
 				memcpy(&cpage_out[outpos],&cpage_out[backoffs],repeat);
-				outpos+=repeat;		
+				outpos+=repeat;
 			}
 		}
 	}
         return 0;
-}		   
+}
 
 static struct jffs3_compressor jffs3_rtime_comp = {
     .priority = JFFS3_RTIME_PRIORITY,

Index: compr_rubin.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/compr_rubin.c,v
retrieving revision 3.3
retrieving revision 3.4
diff -u -r3.3 -r3.4
--- compr_rubin.c	13 Dec 2004 11:35:41 -0000	3.3
+++ compr_rubin.c	25 Dec 2004 11:11:21 -0000	3.4
@@ -12,7 +12,7 @@
  *
  */
 
- 
+
 #include <linux/string.h>
 #include <linux/types.h>
 #include "jffs3.h"
@@ -21,7 +21,7 @@
 #include "compr.h"
 
 static void init_rubin(struct rubin_state *rs, int div, int *bits)
-{	
+{
 	int c;
 
 	rs->q = 0;
@@ -41,7 +41,7 @@
 
 	while ((rs->q >= UPPER_BIT_RUBIN) || ((rs->p + rs->q) <= UPPER_BIT_RUBIN)) {
 		rs->bit_number++;
-		
+
 		ret = pushbit(&rs->pp, (rs->q & UPPER_BIT_RUBIN) ? 1 : 0, 0);
 		if (ret)
 			return ret;
@@ -69,7 +69,7 @@
 
 
 static void end_rubin(struct rubin_state *rs)
-{				
+{
 
 	int i;
 
@@ -83,7 +83,7 @@
 
 static void init_decode(struct rubin_state *rs, int div, int *bits)
 {
-	init_rubin(rs, div, bits);		
+	init_rubin(rs, div, bits);
 
 	/* behalve lower */
 	rs->rec_q = 0;
@@ -189,7 +189,7 @@
 
 
 
-static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in, 
+static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
 		      unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen)
 	{
 	int outpos = 0;
@@ -199,37 +199,37 @@
 	init_pushpull(&rs.pp, cpage_out, *dstlen * 8, 0, 32);
 
 	init_rubin(&rs, bit_divider, bits);
-	
+
 	while (pos < (*sourcelen) && !out_byte(&rs, data_in[pos]))
 		pos++;
-	
+
 	end_rubin(&rs);
 
 	if (outpos > pos) {
 		/* We failed */
 		return -1;
 	}
-	
-	/* Tell the caller how much we managed to compress, 
+
+	/* Tell the caller how much we managed to compress,
 	 * and how much space it took */
-	
+
 	outpos = (pushedbits(&rs.pp)+7)/8;
-	
+
 	if (outpos >= pos)
 		return -1; /* We didn't actually compress */
 	*sourcelen = pos;
 	*dstlen = outpos;
 	return 0;
-}		   
+}
 #if 0
 /* _compress returns the compressed size, -1 if bigger */
-int jffs3_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, 
+int jffs3_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out,
 		   uint32_t *sourcelen, uint32_t *dstlen, void *model)
 {
 	return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
 }
 #endif
-int jffs3_dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out, 
+int jffs3_dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out,
 		   uint32_t *sourcelen, uint32_t *dstlen, void *model)
 {
 	int bits[8];
@@ -276,7 +276,7 @@
 	}
 
 	ret = rubin_do_compress(256, bits, data_in, cpage_out+8, &mysrclen, &mydstlen);
-	if (ret) 
+	if (ret)
 		return ret;
 
 	/* Add back the 8 bytes we took for the probabilities */
@@ -292,29 +292,29 @@
 	return 0;
 }
 
-static void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in, 
+static void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in,
 			 unsigned char *page_out, uint32_t srclen, uint32_t destlen)
 {
 	int outpos = 0;
 	struct rubin_state rs;
-	
+
 	init_pushpull(&rs.pp, cdata_in, srclen, 0, 0);
 	init_decode(&rs, bit_divider, bits);
-	
+
 	while (outpos < destlen) {
 		page_out[outpos++] = in_byte(&rs);
 	}
-}		   
+}
 
 
-int jffs3_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, 
+int jffs3_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out,
 		   uint32_t sourcelen, uint32_t dstlen, void *model)
 {
 	rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
         return 0;
 }
 
-int jffs3_dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, 
+int jffs3_dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out,
 		   uint32_t sourcelen, uint32_t dstlen, void *model)
 {
 	int bits[8];

Index: compr_rubin.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/compr_rubin.h,v
retrieving revision 3.1
retrieving revision 3.2
diff -u -r3.1 -r3.2
--- compr_rubin.h	9 Dec 2004 16:05:04 -0000	3.1
+++ compr_rubin.h	25 Dec 2004 11:11:21 -0000	3.2
@@ -12,8 +12,8 @@
 
 
 struct rubin_state {
-	unsigned long p;		
-	unsigned long q;	
+	unsigned long p;
+	unsigned long q;
 	unsigned long rec_q;
 	long bit_number;
 	struct pushpull pp;

Index: compr_zlib.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/compr_zlib.c,v
retrieving revision 3.3
retrieving revision 3.4
diff -u -r3.3 -r3.4
--- compr_zlib.c	23 Dec 2004 18:53:36 -0000	3.3
+++ compr_zlib.c	25 Dec 2004 11:11:21 -0000	3.4
@@ -25,11 +25,11 @@
 #include "nodelist.h"
 #include "compr.h"
 
-	/* Plan: call deflate() with avail_in == *sourcelen, 
-		avail_out = *dstlen - 12 and flush == Z_FINISH. 
+	/* Plan: call deflate() with avail_in == *sourcelen,
+		avail_out = *dstlen - 12 and flush == Z_FINISH.
 		If it doesn't manage to finish,	call it again with
 		avail_in == 0 and avail_out set to the remaining 12
-		bytes for it to clean up. 
+		bytes for it to clean up.
 	   Q: Is 12 bytes sufficient?
 	*/
 #define STREAM_END_SPACE 12
@@ -70,7 +70,7 @@
 #define free_workspaces() do { } while(0)
 #endif /* __KERNEL__ */
 
-int jffs3_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, 
+int jffs3_zlib_compress(unsigned char *data_in, unsigned char *cpage_out,
 		   uint32_t *sourcelen, uint32_t *dstlen, void *model)
 {
 	int ret;
@@ -88,7 +88,7 @@
 
 	def_strm.next_in = data_in;
 	def_strm.total_in = 0;
-	
+
 	def_strm.next_out = cpage_out;
 	def_strm.total_out = 0;
 
@@ -98,7 +98,7 @@
 		DBG_COMPR(1, "calling deflate with avail_in %d, avail_out %d\n",
 			  def_strm.avail_in, def_strm.avail_out);
 		ret = zlib_deflate(&def_strm, Z_PARTIAL_FLUSH);
-		DBG_COMPR(1, "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n", 
+		DBG_COMPR(1, "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n",
 			  def_strm.avail_in, def_strm.avail_out, def_strm.total_in, def_strm.total_out);
 		if (ret != Z_OK) {
 			DBG_COMPR(1, "deflate in loop returned %d\n", ret);
@@ -147,7 +147,7 @@
 	inf_strm.next_in = data_in;
 	inf_strm.avail_in = srclen;
 	inf_strm.total_in = 0;
-	
+
 	inf_strm.next_out = cpage_out;
 	inf_strm.avail_out = destlen;
 	inf_strm.total_out = 0;

Index: crc32.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/crc32.h,v
retrieving revision 3.1
retrieving revision 3.2
diff -u -r3.1 -r3.2
--- crc32.h	9 Dec 2004 16:05:04 -0000	3.1
+++ crc32.h	25 Dec 2004 11:11:21 -0000	3.2
@@ -10,7 +10,7 @@
 
 /* Return a 32-bit CRC of the contents of the buffer. */
 
-static inline uint32_t 
+static inline uint32_t
 crc32(uint32_t val, const void *ss, int len)
 {
 	const unsigned char *s = ss;

Index: debug.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/debug.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- debug.c	23 Dec 2004 18:53:36 -0000	1.7
+++ debug.c	25 Dec 2004 11:11:21 -0000	1.8
@@ -21,35 +21,16 @@
 #define JFFS3_DBG_BUF_SIZE	4096
 static unsigned char dbg_buf[JFFS3_DBG_BUF_SIZE];
 
-/*
- * Dump the node_refs of the 'jeb' JFFS3 eraseblock.
- */
-static void
-jffs3_dbg_node_refs_dump(struct jffs3_eraseblock *jeb) {
-	struct jffs3_raw_node_ref *ref;
-	int i = 0;
-
-	printk(KERN_DEBUG);
-	for (ref = jeb->first_node; ref; ref = ref->next_phys) {
-		printk("%#08x->", ref_offset(ref));
-		if (++i == 8) {
-			i = 0;
-			printk("\n" KERN_DEBUG);
-		}
-	}
-	printk(KERN_DEBUG "\n");
-}
-
 #define JFFS3_BUFDUMP_BYTES_PER_LINE	8
 void
 jffs3_dbg_dump_buffer(char *buf, int len, uint32_t offs)
 {
 	int i = 0;
 	int skip = offs & ~(JFFS3_BUFDUMP_BYTES_PER_LINE - 1);
-	
+
 	while (i < len) {
 		int j = 0;
-		
+
 		printk(KERN_DEBUG "0x#x: \n");
 		while (skip) {
 			printk("   ");
@@ -73,28 +54,33 @@
 {
 	uint32_t my_used_size = 0;
 	uint32_t my_unchecked_size = 0;
+	uint32_t my_dirty_size = 0;
 	struct jffs3_raw_node_ref *ref2 = jeb->first_node;
 
 	while (ref2) {
+		uint32_t totlen = ref_totlen(c, jeb, ref2);
+
 		if (unlikely(ref2->flash_offset < jeb->offset
 				|| ref2->flash_offset > jeb->offset + c->sector_size)) {
 			ERROR_MSG("node_ref %#08x shouldn't be in block at %#08x!\n",
 				ref_offset(ref2), jeb->offset);
-			node_refs_dump(jeb);
+			jffs3_dbg_dump_node_refs(c, jeb);
 			BUG();
-			
+
 		}
 		if (ref_flags(ref2) == REF_UNCHECKED)
-			my_unchecked_size += ref_totlen(c, jeb, ref2);
+			my_unchecked_size += totlen;
 		else if (!ref_obsolete(ref2))
-			my_used_size += ref_totlen(c, jeb, ref2);
-		
+			my_used_size += totlen;
+		else
+			my_dirty_size += totlen;
+
 		if (unlikely((!ref2->next_phys) != (ref2 == jeb->last_node))) {
 			ERROR_MSG("node_ref for node at %#08x (mem %p) has next_phys at %#08x (mem %p), "
 					"last_node is at %#08x (mem %p)\n",
 					ref_offset(ref2), ref2, ref_offset(ref2->next_phys), ref2->next_phys,
 					ref_offset(jeb->last_node), jeb->last_node);
-			node_refs_dump(jeb);
+			jffs3_dbg_dump_node_refs(c, jeb);
 			BUG();
 		}
 		ref2 = ref2->next_phys;
@@ -105,11 +91,27 @@
 				my_used_size, jeb->used_size);
 		BUG();
 	}
+
 	if (my_unchecked_size != jeb->unchecked_size) {
 		ERROR_MSG("Calculated unchecked size %#08x != stored unchecked size %#08x\n",
 				my_unchecked_size, jeb->unchecked_size);
 		BUG();
 	}
+
+	if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) {
+		ERROR_MSG("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n",
+			my_dirty_size, jeb->dirty_size + jeb->wasted_size);
+		BUG();
+	}
+
+	if (jeb->free_size == 0
+		&& my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) {
+		ERROR_MSG("The sum of all nodes in block (%#x) != size of block (%#x)\n",
+			my_used_size + my_unchecked_size + my_dirty_size,
+			c->sector_size);
+		jffs3_dbg_dump_node_refs(c, jeb);
+		BUG();
+	}
 }
 
 /*
@@ -130,14 +132,14 @@
 					len1, __FUNCTION__, ret, retlen);
 			return;
 		}
-		
+
 		ret = 0;
 		for (i = 0; i < len1; i++) {
 			if (dbg_buf[i] != 0xff) {
 				ret = 1;
 			}
 		}
-		
+
 		if (ret) {
 			ERROR_MSG("ARGH. About to write node to %#08x on flash, but there are data "
 					"already there. The first corrupted byte is at %#08x.\n", ofs, ofs + i);
@@ -159,7 +161,7 @@
 
 	for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
 		struct jffs3_full_dnode *fn = frag->node;
-		
+
 		if (!fn || !fn->raw)
 			continue;
 
@@ -169,7 +171,7 @@
 						ref_offset(fn->raw), fn->frags);
 				bitched = 1;
 			}
-			
+
 			/* A hole node which isn't multi-page should be garbage-collected
 			   and merged anyway, so we just check for the frag size here,
 			   rather than mucking around with actually reading the node
@@ -191,12 +193,10 @@
 			}
 		}
 	}
-	
-	if (bitched) {
-		struct jffs3_node_frag *thisfrag;
 
+	if (bitched) {
 		ERROR_MSG("Fragtree is corrupted. Fragtree dump:\n");
-		jffs3_dbg_print_frag_list(f);
+		jffs3_dbg_dump_frag_list(f);
 		BUG();
 	}
 }
@@ -228,7 +228,7 @@
 				c->nextblock->unchecked_size, c->nextblock->free_size);
 	else
 		printk(KERN_DEBUG "nextblock: NULL\n");
-	
+
 	if (c->gcblock)
 		printk(KERN_DEBUG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
 				"unchecked %#08x, free %#08x)\n",
@@ -236,7 +236,7 @@
 				c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
 	else
 		printk(KERN_DEBUG "gcblock: NULL\n");
-	
+
 	if (list_empty(&c->clean_list)) {
 		printk(KERN_DEBUG "clean_list: empty\n");
 	} else {
@@ -248,12 +248,14 @@
 			struct jffs3_eraseblock *jeb = list_entry(this, struct jffs3_eraseblock, list);
 			numblocks ++;
 			dirty += jeb->wasted_size;
-			printk(KERN_DEBUG "clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
-					"unchecked %#08x, free %#08x)\n",
-					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
-					jeb->unchecked_size, jeb->free_size);
+			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+				printk(KERN_DEBUG "clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
+						"unchecked %#08x, free %#08x)\n",
+						jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+						jeb->unchecked_size, jeb->free_size);
+			}
 		}
-		
+
 		printk (KERN_DEBUG "Contains %d blocks with total wasted size %u, average wasted size: %u\n",
 				numblocks, dirty, dirty / numblocks);
 	}
@@ -267,19 +269,21 @@
 
 		list_for_each(this, &c->very_dirty_list) {
 			struct jffs3_eraseblock *jeb = list_entry(this, struct jffs3_eraseblock, list);
-			
+
 			numblocks ++;
 			dirty += jeb->dirty_size;
-			printk(KERN_DEBUG "very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
-					"unchecked %#08x, free %#08x)\n",
-					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
-					jeb->unchecked_size, jeb->free_size);
+			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+				printk(KERN_DEBUG "very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
+						"unchecked %#08x, free %#08x)\n",
+						jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+						jeb->unchecked_size, jeb->free_size);
+			}
 		}
-		
+
 		printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
 				numblocks, dirty, dirty / numblocks);
 	}
-	
+
 	if (list_empty(&c->dirty_list)) {
 		printk(KERN_DEBUG "dirty_list: empty\n");
 	} else {
@@ -289,13 +293,15 @@
 
 		list_for_each(this, &c->dirty_list) {
 			struct jffs3_eraseblock *jeb = list_entry(this, struct jffs3_eraseblock, list);
-		
+
 			numblocks ++;
 			dirty += jeb->dirty_size;
-			printk(KERN_DEBUG "dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
-					"unchecked %#08x, free %#08x)\n",
-					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
-					jeb->unchecked_size, jeb->free_size);
+			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+				printk(KERN_DEBUG "dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
+						"unchecked %#08x, free %#08x)\n",
+						jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+						jeb->unchecked_size, jeb->free_size);
+			}
 		}
 
 		printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
@@ -309,11 +315,13 @@
 
 		list_for_each(this, &c->erasable_list) {
 			struct jffs3_eraseblock *jeb = list_entry(this, struct jffs3_eraseblock, list);
-			
-			printk(KERN_DEBUG "erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
-					"unchecked %#08x, free %#08x)\n",
-					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
-					jeb->unchecked_size, jeb->free_size);
+
+			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+				printk(KERN_DEBUG "erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
+						"unchecked %#08x, free %#08x)\n",
+						jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+						jeb->unchecked_size, jeb->free_size);
+			}
 		}
 	}
 
@@ -324,14 +332,16 @@
 
 		list_for_each(this, &c->erasing_list) {
 			struct jffs3_eraseblock *jeb = list_entry(this, struct jffs3_eraseblock, list);
-			
-			printk(KERN_DEBUG "erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
-					"unchecked %#08x, free %#08x)\n",
-					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
-					jeb->unchecked_size, jeb->free_size);
+
+			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+				printk(KERN_DEBUG "erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
+						"unchecked %#08x, free %#08x)\n",
+						jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+						jeb->unchecked_size, jeb->free_size);
+			}
 		}
 	}
-	
+
 	if (list_empty(&c->erase_pending_list)) {
 		printk(KERN_DEBUG "erase_pending_list: empty\n");
 	} else {
@@ -339,11 +349,13 @@
 
 		list_for_each(this, &c->erase_pending_list) {
 			struct jffs3_eraseblock *jeb = list_entry(this, struct jffs3_eraseblock, list);
-			
-			printk(KERN_DEBUG "erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
-					"unchecked %#08x, free %#08x)\n",
-					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
-					jeb->unchecked_size, jeb->free_size);
+
+			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+				printk(KERN_DEBUG "erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
+						"unchecked %#08x, free %#08x)\n",
+						jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+						jeb->unchecked_size, jeb->free_size);
+			}
 		}
 	}
 
@@ -354,14 +366,16 @@
 
 		list_for_each(this, &c->erasable_pending_wbuf_list) {
 			struct jffs3_eraseblock *jeb = list_entry(this, struct jffs3_eraseblock, list);
-			
-			printk(KERN_DEBUG "erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, "
-					"wasted %#08x, unchecked %#08x, free %#08x)\n",
-					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
-					jeb->unchecked_size, jeb->free_size);
+
+			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+				printk(KERN_DEBUG "erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, "
+						"wasted %#08x, unchecked %#08x, free %#08x)\n",
+						jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+						jeb->unchecked_size, jeb->free_size);
+			}
 		}
 	}
-	
+
 	if (list_empty(&c->free_list)) {
 		printk(KERN_DEBUG "free_list: empty\n");
 	} else {
@@ -369,14 +383,16 @@
 
 		list_for_each(this, &c->free_list) {
 			struct jffs3_eraseblock *jeb = list_entry(this, struct jffs3_eraseblock, list);
-			
-			printk(KERN_DEBUG "free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
-					"unchecked %#08x, free %#08x)\n",
-					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
-					jeb->unchecked_size, jeb->free_size);
+
+			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+				printk(KERN_DEBUG "free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
+						"unchecked %#08x, free %#08x)\n",
+						jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+						jeb->unchecked_size, jeb->free_size);
+			}
 		}
 	}
-	
+
 	if (list_empty(&c->bad_list)) {
 		printk(KERN_DEBUG "bad_list: empty\n");
 	} else {
@@ -384,14 +400,16 @@
 
 		list_for_each(this, &c->bad_list) {
 			struct jffs3_eraseblock *jeb = list_entry(this, struct jffs3_eraseblock, list);
-			
-			printk(KERN_DEBUG "bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
-					"unchecked %#08x, free %#08x)\n",
-					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
-					jeb->unchecked_size, jeb->free_size);
+
+			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+				printk(KERN_DEBUG "bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
+						"unchecked %#08x, free %#08x)\n",
+						jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+						jeb->unchecked_size, jeb->free_size);
+			}
 		}
 	}
-	
+
 	if (list_empty(&c->bad_used_list)) {
 		printk(KERN_DEBUG "bad_used_list: empty\n");
 	} else {
@@ -399,17 +417,19 @@
 
 		list_for_each(this, &c->bad_used_list) {
 			struct jffs3_eraseblock *jeb = list_entry(this, struct jffs3_eraseblock, list);
-			
-			printk(KERN_DEBUG "bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
-					"unchecked %#08x, free %#08x)\n",
-					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
-					jeb->unchecked_size, jeb->free_size);
+
+			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
+				printk(KERN_DEBUG "bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
+						"unchecked %#08x, free %#08x)\n",
+						jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
+						jeb->unchecked_size, jeb->free_size);
+			}
 		}
 	}
 }
 
 void
-jffs3_dbg_print_frag_list(struct jffs3_inode_info *f)
+jffs3_dbg_dump_frag_list(struct jffs3_inode_info *f)
 {
 	struct jffs3_node_frag *this = frag_first(&f->fragtree);
 	uint32_t lastofs = 0;
@@ -423,7 +443,7 @@
 					this->ofs, this->ofs+this->size, ref_offset(this->node->raw),
 					ref_flags(this->node->raw), this, frag_left(this), frag_right(this),
 					frag_parent(this));
-		else 
+		else
 			printk(KERN_DEBUG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n",
 					this->ofs, this->ofs+this->size, this, frag_left(this),
 					frag_right(this), frag_parent(this));
@@ -432,7 +452,7 @@
 		lastofs = this->ofs+this->size;
 		this = frag_next(this);
 	}
-	
+
 	if (f->metadata)
 		printk(KERN_DEBUG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
 
@@ -443,14 +463,43 @@
 }
 
 void
-jffs3_dbg_print_dirents_list(struct jffs3_full_dirent *list)
+jffs3_dbg_dump_dirents_list(struct jffs3_full_dirent *list)
 {
 	int i = 0;
-	
-	while(*list) {
+
+	while(list) {
 		printk(KERN_DEBUG "%d. Dirent \"%s\" (hash 0x%08x, ino #%u)\n",
 				i++, list->name, list->nhash, list->ino);
 		list = list->next;
 	}
 }
+
+/*
+ * Dump the node_refs of the 'jeb' JFFS3 eraseblock.
+ */
+void
+jffs3_dbg_dump_node_refs(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb) {
+	struct jffs3_raw_node_ref *ref;
+	int i = 0;
+
+	if (!jeb->first_node) {
+		printk(KERN_DEBUG "no nodes in block %#08x\n", jeb->offset);
+		return;
+	}
+
+	printk(KERN_DEBUG);
+	for (ref = jeb->first_node; ; ref = ref->next_phys) {
+		printk("%#08x(%#x)", ref_offset(ref), ref_totlen(c, jeb, ref));
+		if (ref->next_phys)
+			printk("->");
+		else
+			break;
+		if (++i == 4) {
+			i = 0;
+			printk("\n" KERN_DEBUG);
+		}
+	}
+	printk("\n");
+}
+
 #endif /* DEBUG1 > 0 || PARANOIA > 0 */

Index: debug.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/debug.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- debug.h	23 Dec 2004 18:53:36 -0000	1.18
+++ debug.h	25 Dec 2004 11:11:21 -0000	1.19
@@ -41,7 +41,16 @@
  */
 #define SANITY	1
 
-/* 
+/*
+ * TODO: While actively developing JFFS3, keep PARANOIA defined in order
+ * to catch bugs on early stage. This section must be removed later.
+ */
+#if SANITY > 0
+#undef PARANOIA
+#define PARANOIA 1
+#endif
+
+/*
  * JFFS3 subsystems. Used in messaging to distinguish debugging messages
  * from different parts of JFFS3 and to be able to enable/disable
  * messages from different parts of JFFS3 when developing/debugging
@@ -49,7 +58,7 @@
  * Another objective is to have standard output format with prefixed
  * function name, etc. When developing, one may add something else
  * (PID, etc).
- * 
+ *
  * If developing something one may define new subsystem with its own
  * output as well as to split some of already existing, if it is
  * cosiedered to be too large.
@@ -122,55 +131,55 @@
 #define JFFS3DBG_SUBSYSTEM(subsystem, debug_level, args...)			\
 do {										\
 	char *subsysname = NULL;						\
-	if ((debug_level) >= CONFIG_JFFS3_FS_DEBUG) {				\
+	if ((debug_level) <= CONFIG_JFFS3_FS_DEBUG) {				\
 		switch (subsystem) {						\
 			case JFFS3_DBG_WRITE:					\
 				if (JFFS3_DBG_SUBSYS_WRITE_PRINT)		\
-					subsysname = "write";			\
+					subsysname = "write ";			\
 				break;						\
 			case JFFS3_DBG_NR:					\
 				if (JFFS3_DBG_SUBSYS_NR_PRINT)			\
-					subsysname = "nr";			\
+					subsysname = "nref  ";			\
 				break;						\
 			case JFFS3_DBG_BL:					\
 				if (JFFS3_DBG_SUBSYS_BL_PRINT)			\
-					subsysname = "bl";			\
+					subsysname = "bldlst";			\
 				break;						\
 			case JFFS3_DBG_RSV:					\
 				if (JFFS3_DBG_SUBSYS_RSV_PRINT)			\
-					subsysname = "rsv";			\
+					subsysname = "reserv";			\
 				break;						\
 			case JFFS3_DBG_BI:					\
 				if (JFFS3_DBG_SUBSYS_BI_PRINT)			\
-					subsysname = "bi";			\
+					subsysname = "bldino";			\
 				break;						\
 			case JFFS3_DBG_RI:					\
 				if (JFFS3_DBG_SUBSYS_RI_PRINT)			\
-					subsysname = "ri";			\
+					subsysname = "rdino ";			\
 				break;						\
 			case JFFS3_DBG_SUMMARY:					\
 				if (JFFS3_DBG_SUBSYS_SUMMARY_PRINT)		\
-					subsysname = "summary";			\
+					subsysname = "summ  ";			\
 				break;						\
 			case JFFS3_DBG_COMPR:					\
 				if (JFFS3_DBG_SUBSYS_COMPR_PRINT)		\
-					subsysname = "compr";			\
+					subsysname = "compr ";			\
 				break;						\
 			case JFFS3_DBG_BLD:					\
 				if (JFFS3_DBG_SUBSYS_BLD_PRINT)			\
-					subsysname = "build";			\
+					subsysname = "build ";			\
 				break;						\
 			case JFFS3_DBG_VFS:					\
 				if (JFFS3_DBG_SUBSYS_VFS_PRINT)			\
-					subsysname = "VFS";			\
+					subsysname = "VFS   ";			\
 				break;						\
 			case JFFS3_DBG_GCT:					\
 				if (JFFS3_DBG_SUBSYS_GCT_PRINT)			\
-					subsysname = "GCT";			\
+					subsysname = "GCT   ";			\
 				break;						\
 			case JFFS3_DBG_READ:					\
 				if (JFFS3_DBG_SUBSYS_READ_PRINT)		\
-					subsysname = "read";			\
+					subsysname = "read  ";			\
 				break;						\
 			case JFFS3_DBG_SALLOC:					\
 				if (JFFS3_DBG_SUBSYS_SALLOC_PRINT)		\
@@ -178,39 +187,40 @@
 				break;						\
 			case JFFS3_DBG_ERASE:					\
 				if (JFFS3_DBG_SUBSYS_ERASE_PRINT)		\
-					subsysname = "erase";			\
+					subsysname = "erase ";			\
 				break;						\
 			case JFFS3_DBG_SCAN:					\
 				if (JFFS3_DBG_SUBSYS_SCAN_PRINT)		\
-					subsysname = "scan";			\
+					subsysname = "scan  ";			\
 				break;						\
 			case JFFS3_DBG_GC:					\
 				if (JFFS3_DBG_SUBSYS_GC_PRINT)			\
-					subsysname = "GC";			\
+					subsysname = "GC    ";			\
 				break;						\
 			case JFFS3_DBG_WBUF:					\
 				if (JFFS3_DBG_SUBSYS_GC_PRINT)			\
-					subsysname = "wbuf";			\
+					subsysname = "wbuf  ";			\
 				break;						\
 			case JFFS3_DBG_OTHER:					\
 				if (JFFS3_DBG_SUBSYS_OTHER_PRINT)		\
-					subsysname = "";			\
+					subsysname = "other ";			\
 				break;						\
 			default:						\
 				BUG();						\
 		}								\
 		if (subsysname) {						\
-			printk(KERN_DEBUG "[JFFS3 DBG-L%d", debug_level);	\
-			if (subsysname[0])					\
-				printk(", %s] ", subsysname);			\
-			else							\
-				printk("] ");					\
+			printk(KERN_DEBUG "[JFFS3 DBG%d ", debug_level);	\
+			printk("%s] ", subsysname);				\
 			printk("%s(): ", __FUNCTION__);				\
 			printk(args);						\
 		}								\
 	}									\
 } while(0)
 
+/*
+ * All outputs with the following macros are supposed to be removed by the
+ * compiler if the JFFS3 debugging is disabled.
+ */
 #define DBG(debug_level, args...)						\
 	JFFS3DBG_SUBSYSTEM(JFFS3_DBG_OTHER, debug_level, args)
 
@@ -231,7 +241,7 @@
 
 #define DBG_READ(debug_level, args...)						\
 	JFFS3DBG_SUBSYSTEM(JFFS3_DBG_READ, debug_level, args)
-	
+
 #define DBG_GCT(debug_level, args...)						\
 	JFFS3DBG_SUBSYSTEM(JFFS3_DBG_GCT, debug_level, args)
 
@@ -243,7 +253,7 @@
 
 #define DBG_COMPR(debug_level, args...)						\
 	JFFS3DBG_SUBSYSTEM(JFFS3_DBG_COMPR, debug_level, args)
-	
+
 #define DBG_SUMMARY(debug_level, args...)					\
 	JFFS3DBG_SUBSYSTEM(JFFS3_DBG_SUMMARY, debug_level, args)
 
@@ -265,23 +275,23 @@
 #define DBG_WRITE(debug_level, args...)						\
 	JFFS3DBG_SUBSYSTEM(JFFS3_DBG_WRITE, debug_level, args)
 
-/* 
+/*
  * Please, use this macro in case of critical error which makes JFFS3
  * futher unworkable or when you use BUG().
  */
 #define ERROR_MSG(args...)							\
 	do {									\
-		printk(KERN_ERR "[JFFS3] Error in %s(): ", __FUNCTION__);	\
+		printk(KERN_ERR "[JFFS3] ERROR! %s(): ", __FUNCTION__);		\
 		printk(args);							\
 	} while(0)
 
-/* 
+/*
  * Please, use this macro in case of errors which do not make JFFS3
  * unworkable.
  */
 #define WARNING_MSG(args...)							\
 	do {									\
-		printk(KERN_WARNING "[JFFS3] Warning in %s(): ", __FUNCTION__);	\
+		printk(KERN_WARNING "[JFFS3] WARNING! %s(): ", __FUNCTION__);	\
 		printk(args);							\
 	} while(0)
 
@@ -296,9 +306,6 @@
 	} while(0)
 
 void
-jffs3_dbg_node_refs_dump(struct jffs3_eraseblock *jeb);
-	
-void
 jffs3_dbg_acct_paranoia_check(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb);
 
 void
@@ -311,15 +318,19 @@
 jffs3_dbg_dump_block_lists(struct jffs3_sb_info *c);
 
 void
-jffs3_dbg_print_frag_list(struct jffs3_inode_info *f);
+jffs3_dbg_dump_frag_list(struct jffs3_inode_info *f);
 
 void
-jffs3_dbg_print_dirents_list(struct jffs3_full_dirent *list);
-	
+jffs3_dbg_dump_dirents_list(struct jffs3_full_dirent *list);
+
 void
 jffs3_dbg_dump_buffer(char *buf, int len, uint32_t offs);
 
+void
+jffs3_dbg_dump_node_refs(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb);
+
 
+#if SANITY > 0
 /*
  * Check the space accounting of the file system and of the JFFS3 erasable block 'jeb'.
  */
@@ -334,7 +345,7 @@
 				jeb->wasted_size, jeb->unchecked_size, c->sector_size);
 		BUG();
 	}
-	
+
 	if (unlikely(c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size
 				+ c->wasted_size + c->unchecked_size != c->flash_size)) {
 		ERROR_MSG("Eeep. Space accounting superblock info is screwed\n");
@@ -350,7 +361,7 @@
  * Check the wbuf accounting.
  */
 static inline void
-jffs3_dbg_wbuf_acct_sanity_check(struct jffs3_sb_info *c,  struct jffs3_eraseblock *jeb)
+jffs3_dbg_wbuf_acct_sanity_check(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb)
 {
 	if (jeb->free_size < (c->wbuf_pagesize - c->wbuf_len)) {
 		ERROR_MSG("Accounting error. wbuf at %#08x has %#03x bytes, %#03x left.\n",
@@ -361,4 +372,31 @@
 	}
 }
 
+/*
+ * When adding new raw_node_ref, check that it is added just after
+ * previous node.
+ */
+static inline int
+jffs3_dbg_node_add_sanity_check(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb,
+				struct jffs3_raw_node_ref *ref, uint32_t ref_len)
+{
+	/*
+	 * During mounting c->nextblock may be uninitialized, so don't
+	 * check it if JFFS3_SB_FLAG_MOUNTING flag is set.
+	 */
+	if ((!(c->flags & JFFS3_SB_FLAG_MOUNTING) && jeb != c->nextblock)
+		|| ref_offset(ref) != jeb->offset + (c->sector_size - jeb->free_size)) {
+		WARNING_MSG("Argh. Node added in wrong place.\n");
+		printk(KERN_ERR "c->nextblock %p, jeb %p, new offs %#08x, new len %#x, "
+			"should be %#08x (jeb->offset %#08x, c->sector_size %#x, "
+			"jeb->free_size %#x)\n", c->nextblock, jeb,
+			ref_offset(ref), ref_len, jeb->offset + (c->sector_size - jeb->free_size),
+			jeb->offset, c->sector_size, jeb->free_size);
+		return -1;
+	}
+
+	return 0;
+}
+#endif
+
 #endif /* __JFFS3_DEBUG_H__ */

Index: dir.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/dir.c,v
retrieving revision 3.5
retrieving revision 3.6
diff -u -r3.5 -r3.6
--- dir.c	21 Dec 2004 15:18:50 -0000	3.5
+++ dir.c	25 Dec 2004 11:11:21 -0000	3.6
@@ -20,6 +20,7 @@
 #include <linux/time.h>
 #include "jffs3.h"
 #include "nodelist.h"
+#include "summary.h"
 
 /* Urgh. Please tell me there's a nicer way of doing these. */
 #include <linux/version.h>
@@ -73,7 +74,7 @@
 
 
 /* We keep the dirent list sorted in increasing order of name hash,
-   and we use the same hash function as the dentries. Makes this 
+   and we use the same hash function as the dentries. Makes this
    nice and simple
 */
 static struct dentry *jffs3_lookup(struct inode *dir_i, struct dentry *target,
@@ -94,7 +95,7 @@
 
 	/* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */
 	for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= target->d_name.hash; fd_list = fd_list->next) {
-		if (fd_list->nhash == target->d_name.hash && 
+		if (fd_list->nhash == target->d_name.hash &&
 		    (!fd || fd_list->version > fd->version) &&
 		    strlen(fd_list->name) == target->d_name.len &&
 		    !strncmp(fd_list->name, target->d_name.name, target->d_name.len)) {
@@ -156,7 +157,7 @@
 		curofs++;
 		/* First loop: curofs = 2; offset = 2 */
 		if (curofs < offset) {
-			DBG_VFS(2, "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n", 
+			DBG_VFS(2, "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n",
 				  fd->name, fd->ino, fd->type, curofs, offset);
 			continue;
 		}
@@ -191,7 +192,7 @@
 	ri = jffs3_alloc_raw_inode();
 	if (!ri)
 		return -ENOMEM;
-	
+
 	c = JFFS3_SB_INFO(dir_i->i_sb);
 
 	DBG_VFS(1, "entering\n");
@@ -212,7 +213,7 @@
 	f = JFFS3_INODE_INFO(inode);
 	dir_f = JFFS3_INODE_INFO(dir_i);
 
-	ret = jffs3_do_create(c, dir_f, f, ri, 
+	ret = jffs3_do_create(c, dir_f, f, ri,
 			      dentry->d_name.name, dentry->d_name.len);
 
 	if (ret) {
@@ -243,7 +244,7 @@
 	struct jffs3_inode_info *dead_f = JFFS3_INODE_INFO(dentry->d_inode);
 	int ret;
 
-	ret = jffs3_do_unlink(c, dir_f, dentry->d_name.name, 
+	ret = jffs3_do_unlink(c, dir_f, dentry->d_name.name,
 			       dentry->d_name.len, dead_f);
 	if (dead_f->inocache)
 		dentry->d_inode->i_nlink = dead_f->inocache->nlink;
@@ -307,11 +308,11 @@
 
 	if (!ri)
 		return -ENOMEM;
-	
+
 	c = JFFS3_SB_INFO(dir_i->i_sb);
-	
-	/* Try to reserve enough space for both node and dirent. 
-	 * Just the node will do for now, though 
+
+	/* Try to reserve enough space for both node and dirent.
+	 * Just the node will do for now, though
 	 */
 	namelen = dentry->d_name.len;
 	ret = jffs3_reserve_space(c, sizeof(*ri) + strlen(target), &phys_ofs, &alloclen, ALLOC_NORMAL,  JFFS3_SUMMARY_INODE_SIZE);
@@ -341,7 +342,7 @@
 	ri->compr = JFFS3_COMPR_NONE;
 	ri->data_crc = cpu_to_je32(crc32(0, target, strlen(target)));
 	ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-	
+
 	fn = jffs3_write_dnode(c, f, ri, target, strlen(target), phys_ofs, ALLOC_NORMAL);
 
 	jffs3_free_raw_inode(ri);
@@ -353,7 +354,7 @@
 		jffs3_clear_inode(inode);
 		return PTR_ERR(fn);
 	}
-	/* No data here. Only a metadata node, which will be 
+	/* No data here. Only a metadata node, which will be
 	   obsoleted by the first data write
 	*/
 	f->metadata = fn;
@@ -395,7 +396,7 @@
 	fd = jffs3_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
 
 	if (IS_ERR(fd)) {
-		/* dirent failed to write. Delete the inode normally 
+		/* dirent failed to write. Delete the inode normally
 		   as if it were the final unlink() */
 		jffs3_complete_reservation(c);
 		jffs3_free_raw_dirent(rd);
@@ -438,11 +439,11 @@
 	ri = jffs3_alloc_raw_inode();
 	if (!ri)
 		return -ENOMEM;
-	
+
 	c = JFFS3_SB_INFO(dir_i->i_sb);
 
-	/* Try to reserve enough space for both node and dirent. 
-	 * Just the node will do for now, though 
+	/* Try to reserve enough space for both node and dirent.
+	 * Just the node will do for now, though
 	 */
 	namelen = dentry->d_name.len;
 	ret = jffs3_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_INODE_SIZE);
@@ -469,7 +470,7 @@
 
 	ri->data_crc = cpu_to_je32(0);
 	ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-	
+
 	fn = jffs3_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
 
 	jffs3_free_raw_inode(ri);
@@ -481,7 +482,7 @@
 		jffs3_clear_inode(inode);
 		return PTR_ERR(fn);
 	}
-	/* No data here. Only a metadata node, which will be 
+	/* No data here. Only a metadata node, which will be
 	   obsoleted by the first data write
 	*/
 	f->metadata = fn;
@@ -494,7 +495,7 @@
 		jffs3_clear_inode(inode);
 		return ret;
 	}
-	
+
 	rd = jffs3_alloc_raw_dirent();
 	if (!rd) {
 		/* Argh. Now we treat it like a normal delete */
@@ -521,9 +522,9 @@
 	rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
 
 	fd = jffs3_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
-	
+
 	if (IS_ERR(fd)) {
-		/* dirent failed to write. Delete the inode normally 
+		/* dirent failed to write. Delete the inode normally
 		   as if it were the final unlink() */
 		jffs3_complete_reservation(c);
 		jffs3_free_raw_dirent(rd);
@@ -585,16 +586,16 @@
 	ri = jffs3_alloc_raw_inode();
 	if (!ri)
 		return -ENOMEM;
-	
+
 	c = JFFS3_SB_INFO(dir_i->i_sb);
-	
+
 	if (S_ISBLK(mode) || S_ISCHR(mode)) {
 		dev = cpu_to_je16(old_encode_dev(rdev));
 		devlen = sizeof(dev);
 	}
-	
-	/* Try to reserve enough space for both node and dirent. 
-	 * Just the node will do for now, though 
+
+	/* Try to reserve enough space for both node and dirent.
+	 * Just the node will do for now, though
 	 */
 	namelen = dentry->d_name.len;
 	ret = jffs3_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_INODE_SIZE);
@@ -623,7 +624,7 @@
 	ri->compr = JFFS3_COMPR_NONE;
 	ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen));
 	ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-	
+
 	fn = jffs3_write_dnode(c, f, ri, (char *)&dev, devlen, phys_ofs, ALLOC_NORMAL);
 
 	jffs3_free_raw_inode(ri);
@@ -635,7 +636,7 @@
 		jffs3_clear_inode(inode);
 		return PTR_ERR(fn);
 	}
-	/* No data here. Only a metadata node, which will be 
+	/* No data here. Only a metadata node, which will be
 	   obsoleted by the first data write
 	*/
 	f->metadata = fn;
@@ -678,9 +679,9 @@
 	rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
 
 	fd = jffs3_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
-	
+
 	if (IS_ERR(fd)) {
-		/* dirent failed to write. Delete the inode normally 
+		/* dirent failed to write. Delete the inode normally
 		   as if it were the final unlink() */
 		jffs3_complete_reservation(c);
 		jffs3_free_raw_dirent(rd);
@@ -713,7 +714,7 @@
 	struct jffs3_inode_info *victim_f = NULL;
 	uint8_t type;
 
-	/* The VFS will check for us and prevent trying to rename a 
+	/* The VFS will check for us and prevent trying to rename a
 	 * file over a directory and vice versa, but if it's a directory,
 	 * the VFS can't check whether the victim is empty. The filesystem
 	 * needs to do that for itself.
@@ -735,17 +736,17 @@
 	}
 
 	/* XXX: We probably ought to alloc enough space for
-	   both nodes at the same time. Writing the new link, 
+	   both nodes at the same time. Writing the new link,
 	   then getting -ENOSPC, is quite bad :)
 	*/
 
 	/* Make a hard link */
-	
+
 	/* XXX: This is ugly */
 	type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
 	if (!type) type = DT_REG;
 
-	ret = jffs3_do_link(c, JFFS3_INODE_INFO(new_dir_i), 
+	ret = jffs3_do_link(c, JFFS3_INODE_INFO(new_dir_i),
 			    old_dentry->d_inode->i_ino, type,
 			    new_dentry->d_name.name, new_dentry->d_name.len);
 
@@ -764,13 +765,13 @@
 		}
 	}
 
-	/* If it was a directory we moved, and there was no victim, 
+	/* If it was a directory we moved, and there was no victim,
 	   increase i_nlink on its new parent */
 	if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f)
 		new_dir_i->i_nlink++;
 
 	/* Unlink the original */
-	ret = jffs3_do_unlink(c, JFFS3_INODE_INFO(old_dir_i), 
+	ret = jffs3_do_unlink(c, JFFS3_INODE_INFO(old_dir_i),
 		      old_dentry->d_name.name, old_dentry->d_name.len, NULL);
 
 	/* We don't touch inode->i_nlink */

Index: erase.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/erase.c,v
retrieving revision 3.5
retrieving revision 3.6
diff -u -r3.5 -r3.6
--- erase.c	23 Dec 2004 18:53:36 -0000	3.5
+++ erase.c	25 Dec 2004 11:11:21 -0000	3.6
@@ -25,7 +25,7 @@
 	struct jffs3_eraseblock *jeb;
 	struct jffs3_sb_info *c;
 };
-      
+
 #ifndef __ECOS
 static void jffs3_erase_callback(struct erase_info *);
 #endif
@@ -72,7 +72,7 @@
 	instr->callback = jffs3_erase_callback;
 	instr->priv = (unsigned long)(&instr[1]);
 	instr->fail_addr = 0xffffffff;
-	
+
 	((struct erase_priv_struct *)instr->priv)->jeb = jeb;
 	((struct erase_priv_struct *)instr->priv)->c = c;
 
@@ -97,7 +97,7 @@
 		return;
 	}
 
-	if (ret == -EROFS) 
+	if (ret == -EROFS)
 		WARNING_MSG("Erase at %#08x failed immediately: -EROFS. Is the sector locked?\n", jeb->offset);
 	else
 		WARNING_MSG("Erase at %#08x failed immediately: errno %d\n", jeb->offset, ret);
@@ -198,7 +198,7 @@
 	c->nr_erasing_blocks--;
 	spin_unlock(&c->erase_completion_lock);
 	wake_up(&c->erase_wait);
-}	 
+}
 
 #ifndef __ECOS
 static void jffs3_erase_callback(struct erase_info *instr)
@@ -211,7 +211,7 @@
 		jffs3_erase_failed(priv->c, priv->jeb, instr->fail_addr);
 	} else {
 		jffs3_erase_succeeded(priv->c, priv->jeb);
-	}	
+	}
 	kfree(instr);
 }
 #endif /* !__ECOS */
@@ -229,13 +229,13 @@
 	/* Walk the inode's list once, removing any nodes from this eraseblock */
 	while (1) {
 		if (!(*prev)->next_in_ino) {
-			/* We're looking at the jffs3_inode_cache, which is 
+			/* We're looking at the jffs3_inode_cache, which is
 			   at the end of the linked list. Stash it and continue
 			   from the beginning of the list */
 			ic = (struct jffs3_inode_cache *)(*prev);
 			prev = &ic->nodes;
 			continue;
-		} 
+		}
 
 		if (((*prev)->flash_offset & ~(c->sector_size -1)) == jeb->offset) {
 			/* It's in the block we're erasing */
@@ -277,12 +277,14 @@
 	while(jeb->first_node) {
 		ref = jeb->first_node;
 		jeb->first_node = ref->next_phys;
-		
+
 		/* Remove from the inode-list */
 		if (ref->next_in_ino)
 			jffs3_remove_node_refs_from_ino_list(c, ref, jeb);
 		/* else it was a non-inode node or already removed, so don't bother */
 
+		DBG_ERASE(2, "Free ref at %#08x(%#x), len %x\n",
+			ref_offset(ref), ref_flags(ref), ref_totlen(c, jeb, ref));
 		jffs3_free_raw_node_ref(ref);
 	}
 	jeb->last_node = NULL;
@@ -340,7 +342,7 @@
 					bad_offset += i;
 					WARNING_MSG("Newly-erased block contained word 0x%lx "
 							"at offset %#08x\n", datum, bad_offset);
-				bad: 
+				bad:
 					if (!jffs3_cleanmarker_oob(c))
 						jffs3_free_raw_node_ref(marker_ref);
 					kfree(ebuf);
@@ -364,13 +366,13 @@
 
 	bad_offset = jeb->offset;
 
-	/* Write the erase complete marker */	
+	/* Write the erase complete marker */
 	DBG_ERASE(1, "Writing erased marker to block at %#08x\n", jeb->offset);
 	if (jffs3_cleanmarker_oob(c)) {
 
 		if (jffs3_write_nand_cleanmarker(c, jeb))
 			goto bad2;
-			
+
 		jeb->first_node = jeb->last_node = NULL;
 
 		jeb->free_size = c->sector_size;
@@ -390,7 +392,7 @@
 		vecs[0].iov_base = (unsigned char *) &marker;
 		vecs[0].iov_len = sizeof(marker);
 		ret = jffs3_flash_direct_writev(c, vecs, 1, jeb->offset, &retlen);
-		
+
 		if (ret) {
 			WARNING_MSG("Write clean marker to block at %#08x failed: %d\n",
 				       jeb->offset, ret);
@@ -405,10 +407,12 @@
 		marker_ref->next_in_ino = NULL;
 		marker_ref->next_phys = NULL;
 		marker_ref->flash_offset = jeb->offset | REF_NORMAL;
+#ifdef TMP_TOTLEN
 		marker_ref->__totlen = c->cleanmarker_size;
-			
+#endif
+
 		jeb->first_node = jeb->last_node = marker_ref;
-			
+
 		jeb->free_size = c->sector_size - c->cleanmarker_size;
 		jeb->used_size = c->cleanmarker_size;
 		jeb->dirty_size = 0;

Index: file.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/file.c,v
retrieving revision 3.5
retrieving revision 3.6
diff -u -r3.5 -r3.6
--- file.c	21 Dec 2004 15:18:50 -0000	3.5
+++ file.c	25 Dec 2004 11:11:21 -0000	3.6
@@ -22,6 +22,7 @@
 #include <linux/crc32.h>
 #include "jffs3.h"
 #include "nodelist.h"
+#include "summary.h"
 
 extern int generic_file_open(struct inode *, struct file *) __attribute__((weak));
 extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) __attribute__((weak));
@@ -34,8 +35,8 @@
 
 	/* Trigger GC to flush any pending writes for this inode */
 	jffs3_flush_wbuf_gc(c, inode->i_ino);
-			
-	return 0;	
+
+	return 0;
 }
 
 struct file_operations jffs3_file_operations =
@@ -73,7 +74,8 @@
 	unsigned char *pg_buf;
 	int ret;
 
-	DBG_VFS(2, "ino #%lu, page at offset 0x%lx\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT);
+	DBG_VFS(2, "Inode #%lu, page at offset 0x%lx\n",
+		inode->i_ino, pg->index << PAGE_CACHE_SHIFT);
 
 	if (!PageLocked(pg))
                 PAGE_BUG(pg);
@@ -94,7 +96,7 @@
 	flush_dcache_page(pg);
 	kunmap(pg);
 
-	DBG_VFS(2,"readpage finished\n");
+	DBG_VFS(2,"Finished\n");
 	return 0;
 }
 
@@ -110,7 +112,7 @@
 {
 	struct jffs3_inode_info *f = JFFS3_INODE_INFO(pg->mapping->host);
 	int ret;
-	
+
 	down(&f->sem);
 	ret = jffs3_do_readpage_unlock(pg->mapping->host, pg);
 	up(&f->sem);
@@ -124,7 +126,7 @@
 	uint32_t pageofs = pg->index << PAGE_CACHE_SHIFT;
 	int ret = 0;
 
-	DBG_VFS(1, "entering\n");
+	DBG_VFS(1, "Prepare write %#x-%#x\n", start, end);
 
 	if (pageofs > inode->i_size) {
 		/* Make new hole frag from old EOF to new page */
@@ -132,8 +134,8 @@
 		struct jffs3_raw_inode ri;
 		struct jffs3_full_dnode *fn;
 		uint32_t phys_ofs, alloc_len;
-		
-		DBG_VFS(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
+
+		DBG_VFS(1, "Writing new hole frag %#x-%#x between current EOF and new page\n",
 			  (unsigned int)inode->i_size, pageofs);
 
 		ret = jffs3_reserve_space(c, sizeof(ri), &phys_ofs, &alloc_len, ALLOC_NORMAL, JFFS3_SUMMARY_INODE_SIZE);
@@ -161,7 +163,7 @@
 		ri.compr = JFFS3_COMPR_ZERO;
 		ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
 		ri.data_crc = cpu_to_je32(0);
-		
+
 		fn = jffs3_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
 
 		if (IS_ERR(fn)) {
@@ -188,14 +190,14 @@
 		inode->i_size = pageofs;
 		up(&f->sem);
 	}
-	
+
 	/* Read in the page if it wasn't already present, unless it's a whole page */
 	if (!PageUptodate(pg) && (start || end < PAGE_CACHE_SIZE)) {
 		down(&f->sem);
 		ret = jffs3_do_readpage_nolock(inode, pg);
 		up(&f->sem);
 	}
-	DBG_VFS(1, "end. pg->flags %lx\n", pg->flags);
+	DBG_VFS(1, "Finished. pg->flags %lx\n", pg->flags);
 	return ret;
 }
 
@@ -212,13 +214,13 @@
 	int ret = 0;
 	uint32_t writtenlen = 0;
 
-	DBG_VFS(1, "ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n",
+	DBG_VFS(1, "Inode #%lu, page %#lx, range %#x-%#x, flags %#lx\n",
 		  inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags);
 
 	if (!start && end == PAGE_CACHE_SIZE) {
 		/* We need to avoid deadlock with page_cache_read() in
 		   jffs3_garbage_collect_pass(). So we have to mark the
-		   page up to date, to prevent page_cache_read() from 
+		   page up to date, to prevent page_cache_read() from
 		   trying to re-lock it. */
 		SetPageUptodate(pg);
 	}
@@ -252,7 +254,7 @@
 		/* There was an error writing. */
 		SetPageError(pg);
 	}
-	
+
 	/* Adjust writtenlen for the padding we did, so we don't confuse our caller */
 	if (writtenlen < (start&3))
 		writtenlen = 0;
@@ -263,7 +265,7 @@
 		if (inode->i_size < (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen) {
 			inode->i_size = (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen;
 			inode->i_blocks = (inode->i_size + 511) >> 9;
-			
+
 			inode->i_ctime = inode->i_mtime = ITIME(je32_to_cpu(ri->ctime));
 		}
 	}
@@ -272,7 +274,7 @@
 
 	if (start+writtenlen < end) {
 		/* generic_file_write has written more to the page cache than we've
-		   actually written to the medium. Mark the page !Uptodate so that 
+		   actually written to the medium. Mark the page !Uptodate so that
 		   it gets reread */
 		DBG_VFS(1, "Not all bytes written. Marking page !uptodate\n");
 		SetPageError(pg);

Index: fs.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/fs.c,v
retrieving revision 3.6
retrieving revision 3.7
diff -u -r3.6 -r3.7
--- fs.c	23 Dec 2004 18:53:36 -0000	3.6
+++ fs.c	25 Dec 2004 11:11:21 -0000	3.7
@@ -25,7 +25,7 @@
 #include <linux/vfs.h>
 #include <linux/crc32.h>
 #include "nodelist.h"
-
+#include "summary.h"
 
 static int jffs3_do_setattr (struct inode *inode, struct iattr *iattr)
 {
@@ -39,11 +39,11 @@
 	unsigned int ivalid;
 	uint32_t phys_ofs, alloclen;
 	int ret;
-	
+
 	DBG_VFS(1, "ino #%lu\n", inode->i_ino);
-	
+
 	ret = inode_change_ok(inode, iattr);
-	if (ret) 
+	if (ret)
 		return ret;
 
 	/* Special cases - we don't want more than one data node
@@ -76,7 +76,7 @@
 			kfree(mdata);
 		return -ENOMEM;
 	}
-		
+
 	ret = jffs3_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_INODE_SIZE);
 	if (ret) {
 		jffs3_free_raw_inode(ri);
@@ -86,7 +86,7 @@
 	}
 	down(&f->sem);
 	ivalid = iattr->ia_valid;
-	
+
 	ri->magic = cpu_to_je16(JFFS3_MAGIC_BITMASK);
 	ri->nodetype = cpu_to_je16(JFFS3_NODETYPE_INODE);
 	ri->totlen = cpu_to_je32(sizeof(*ri) + mdatalen);
@@ -102,7 +102,7 @@
 		if (iattr->ia_mode & S_ISGID &&
 		    !in_group_p(je16_to_cpu(ri->gid)) && !capable(CAP_FSETID))
 			ri->mode = cpu_to_jemode(iattr->ia_mode & ~S_ISGID);
-		else 
+		else
 			ri->mode = cpu_to_jemode(iattr->ia_mode);
 	else
 		ri->mode = cpu_to_jemode(inode->i_mode);
@@ -131,7 +131,7 @@
 	new_metadata = jffs3_write_dnode(c, f, ri, mdata, mdatalen, phys_ofs, ALLOC_NORMAL);
 	if (S_ISLNK(inode->i_mode))
 		kfree(mdata);
-	
+
 	if (IS_ERR(new_metadata)) {
 		jffs3_complete_reservation(c);
 		jffs3_free_raw_inode(ri);
@@ -169,7 +169,7 @@
 	jffs3_complete_reservation(c);
 
 	/* We have to do the vmtruncate() without f->sem held, since
-	   some pages may be locked and waiting for it in readpage(). 
+	   some pages may be locked and waiting for it in readpage().
 	   We are protected from a simultaneous write() extending i_size
 	   back past iattr->ia_size, because do_truncate() holds the
 	   generic inode semaphore. */
@@ -179,12 +179,12 @@
 	return 0;
 }
 
-int jffs3_setattr(struct dentry *dentry, struct iattr *iattr)
+int jffs3_setattr (struct dentry *dentry, struct iattr *iattr)
 {
 	return jffs3_do_setattr(dentry->d_inode, iattr);
 }
 
-int jffs3_statfs(struct super_block *sb, struct kstatfs *buf)
+int jffs3_statfs (struct super_block *sb, struct kstatfs *buf)
 {
 	struct jffs3_sb_info *c = JFFS3_SB_INFO(sb);
 	unsigned long avail;
@@ -219,13 +219,13 @@
 
 void jffs3_clear_inode (struct inode *inode)
 {
-	/* We can forget about this inode for now - drop all 
+	/* We can forget about this inode for now - drop all
 	 *  the nodelists associated with it, etc.
 	 */
 	struct jffs3_sb_info *c = JFFS3_SB_INFO(inode->i_sb);
 	struct jffs3_inode_info *f = JFFS3_INODE_INFO(inode);
-	
-	DBG_VFS(1, "ino #%lu mode %o\n", inode->i_ino, inode->i_mode);
+
+	DBG_VFS(1, "Clear ino #%lu, mode %o\n", inode->i_ino, inode->i_mode);
 
 	jffs3_do_clear_inode(c, f);
 }
@@ -237,13 +237,13 @@
 	struct jffs3_raw_inode latest_node;
 	int ret;
 
-	DBG_VFS(1, "inode->i_ino == %lu\n", inode->i_ino);
+	DBG_VFS(1, "Read ino #%lu\n", inode->i_ino);
 
 	f = JFFS3_INODE_INFO(inode);
 	c = JFFS3_SB_INFO(inode->i_sb);
 
 	jffs3_init_inode_info(f);
-	
+
 	ret = jffs3_do_read_inode(c, f, inode->i_ino, &latest_node);
 
 	if (ret) {
@@ -263,14 +263,14 @@
 
 	inode->i_blksize = PAGE_SIZE;
 	inode->i_blocks = (inode->i_size + 511) >> 9;
-	
+
 	switch (inode->i_mode & S_IFMT) {
 		jint16_t rdev;
 
 	case S_IFLNK:
 		inode->i_op = &jffs3_symlink_inode_operations;
 		break;
-		
+
 	case S_IFDIR:
 	{
 		struct jffs3_full_dirent *fd;
@@ -307,7 +307,7 @@
 			jffs3_do_clear_inode(c, f);
 			make_bad_inode(inode);
 			return;
-		}			
+		}
 
 	case S_IFSOCK:
 	case S_IFIFO:
@@ -317,24 +317,29 @@
 		break;
 
 	default:
-		WARNING_MSG("Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino);
+		WARNING_MSG("Bogus i_mode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino);
 	}
 
 	up(&f->sem);
 
-	DBG_VFS(1, "returning\n");
+	DBG_VFS(1, "Inode #%u was read\n", f->inocache->ino);
+	DBG_VFS(2, "Inode nlink %d, state %d, highest_version %d, flags %#x, "
+			"fragtree root node %p, dents %p, metadata %p\n",
+			f->inocache->nlink, f->inocache->state,
+			f->highest_version, f->flags, f->fragtree.rb_node,
+			f->dents, f->metadata);
 }
 
-void jffs3_dirty_inode(struct inode *inode)
+void jffs3_dirty_inode (struct inode *inode)
 {
 	struct iattr iattr;
 
 	if (!(inode->i_state & I_DIRTY_DATASYNC)) {
-		DBG_VFS(2, "calling setattr() for ino #%lu\n", inode->i_ino);
+		DBG_VFS(2, "Calling setattr() for ino #%lu\n", inode->i_ino);
 		return;
 	}
 
-	DBG_VFS(1, "calling setattr() for ino #%lu\n", inode->i_ino);
+	DBG_VFS(1, "Calling setattr() for ino #%lu\n", inode->i_ino);
 
 	iattr.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_MTIME|ATTR_CTIME;
 	iattr.ia_mode = inode->i_mode;
@@ -363,11 +368,11 @@
 		down(&c->alloc_sem);
 		jffs3_flush_wbuf_pad(c);
 		up(&c->alloc_sem);
-	}	
+	}
 
 	if (!(*flags & MS_RDONLY))
 		jffs3_start_garbage_collect_thread(c);
-	
+
 	*flags |= MS_NOATIME;
 
 	return 0;
@@ -381,7 +386,7 @@
 	if (sb->s_flags & MS_RDONLY)
 		return;
 
-	DBG_VFS(1, "entering\n");
+	DBG_VFS(1, "Entering\n");
 	jffs3_garbage_collect_trigger(c);
 	jffs3_erase_pending_blocks(c, 0);
 	jffs3_flush_wbuf_gc(c, 0);
@@ -401,9 +406,9 @@
 	DBG_VFS(1, "dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode);
 
 	c = JFFS3_SB_INFO(sb);
-	
+
 	inode = new_inode(sb);
-	
+
 	if (!inode)
 		return ERR_PTR(-ENOMEM);
 
@@ -464,30 +469,30 @@
 
 	c->flash_size = c->mtd->size;
 
-	/* 
+	/*
 	 * Check, if we have to concatenate physical blocks to larger virtual blocks
 	 * to reduce the memorysize for c->blocks. (kmalloc allows max. 128K allocation)
 	 */
-	c->sector_size = c->mtd->erasesize; 
+	c->sector_size = c->mtd->erasesize;
 	blocks = c->flash_size / c->sector_size;
 	if (!(c->mtd->flags & MTD_NO_VIRTBLOCKS)) {
 		while ((blocks * sizeof (struct jffs3_eraseblock)) > (128 * 1024)) {
 			blocks >>= 1;
 			c->sector_size <<= 1;
-		}	
+		}
 	}
 
 	/*
 	 * Size alignment check
 	 */
 	if ((c->sector_size * blocks) != c->flash_size) {
-		c->flash_size = c->sector_size * blocks;		
+		c->flash_size = c->sector_size * blocks;
 		NOTICE_MSG("Flash size not aligned to erasesize, reducing to %dKiB\n",
 				c->flash_size / 1024);
 	}
 
 	if (c->sector_size != c->mtd->erasesize)
-		NOTICE_MSG("Erase block size too small (%dKiB). Using virtual blocks size (%dKiB) instead\n", 
+		NOTICE_MSG("Erase block size too small (%dKiB). Using virtual blocks size (%dKiB) instead\n",
 			c->mtd->erasesize / 1024, c->sector_size / 1024);
 
 	if (c->flash_size < 5*c->sector_size) {
@@ -518,11 +523,10 @@
 	DBG_VFS(1, "Getting root inode\n");
 	root_i = iget(sb, 1);
 	if (is_bad_inode(root_i)) {
-		WARNING_MSG("get root inode failed\n");
+		WARNING_MSG("Get root inode failed\n");
 		goto out_nodes;
 	}
 
-	DBG_VFS(1, "d_alloc_root()\n");
 	sb->s_root = d_alloc_root(root_i);
 	if (!sb->s_root)
 		goto out_root_i;
@@ -567,16 +571,16 @@
 	struct jffs3_inode_cache *ic;
 	if (!nlink) {
 		/* The inode has zero nlink but its nodes weren't yet marked
-		   obsolete. This has to be because we're still waiting for 
+		   obsolete. This has to be because we're still waiting for
 		   the final (close() and) iput() to happen.
 
-		   There's a possibility that the final iput() could have 
+		   There's a possibility that the final iput() could have
 		   happened while we were contemplating. In order to ensure
 		   that we don't cause a new read_inode() (which would fail)
 		   for the inode in question, we use ilookup() in this case
 		   instead of iget().
 
-		   The nlink can't _become_ zero at this point because we're 
+		   The nlink can't _become_ zero at this point because we're
 		   holding the alloc_sem, and jffs3_do_unlink() would also
 		   need that while decrementing nlink on any inode.
 		*/
@@ -620,19 +624,19 @@
 	return JFFS3_INODE_INFO(inode);
 }
 
-unsigned char *jffs3_gc_fetch_page(struct jffs3_sb_info *c, 
-				   struct jffs3_inode_info *f, 
+unsigned char *jffs3_gc_fetch_page(struct jffs3_sb_info *c,
+				   struct jffs3_inode_info *f,
 				   unsigned long offset,
 				   unsigned long *priv)
 {
 	struct inode *inode = OFNI_EDONI_2SFFJ(f);
 	struct page *pg;
 
-	pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT, 
+	pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT,
 			     (void *)jffs3_do_readpage_unlock, inode);
 	if (IS_ERR(pg))
 		return (void *)pg;
-	
+
 	*priv = (unsigned long)pg;
 	return kmap(pg);
 }
@@ -649,7 +653,7 @@
 
 int jffs3_flash_setup(struct jffs3_sb_info *c) {
 	int ret = 0;
-	
+
 	if (jffs3_cleanmarker_oob(c)) {
 		/* NAND flash... do setup accordingly */
 		ret = jffs3_nand_flash_setup(c);

Index: gc.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/gc.c,v
retrieving revision 3.8
retrieving revision 3.9
diff -u -r3.8 -r3.9
--- gc.c	22 Dec 2004 18:35:51 -0000	3.8
+++ gc.c	25 Dec 2004 11:11:21 -0000	3.9
@@ -21,15 +21,16 @@
 #include <linux/stat.h>
 #include "nodelist.h"
 #include "compr.h"
+#include "summary.h"
 
-static int jffs3_garbage_collect_pristine(struct jffs3_sb_info *c, 
+static int jffs3_garbage_collect_pristine(struct jffs3_sb_info *c,
 					  struct jffs3_inode_cache *ic,
 					  struct jffs3_raw_node_ref *raw);
-static int jffs3_garbage_collect_metadata(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb, 
+static int jffs3_garbage_collect_metadata(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb,
 					struct jffs3_inode_info *f, struct jffs3_full_dnode *fd);
-static int jffs3_garbage_collect_dirent(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb, 
+static int jffs3_garbage_collect_dirent(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb,
 					struct jffs3_inode_info *f, struct jffs3_full_dirent *fd);
-static int jffs3_garbage_collect_deletion_dirent(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb, 
+static int jffs3_garbage_collect_deletion_dirent(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb,
 					struct jffs3_inode_info *f, struct jffs3_full_dirent *fd);
 static int jffs3_garbage_collect_hole(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb,
 				      struct jffs3_inode_info *f, struct jffs3_full_dnode *fn,
@@ -55,7 +56,7 @@
 		DBG_GC(1, "Picking block from bad_used_list to GC next\n");
 		nextlist = &c->bad_used_list;
 	} else if (n < 50 && !list_empty(&c->erasable_list)) {
-		/* Note that most of them will have gone directly to be erased. 
+		/* Note that most of them will have gone directly to be erased.
 		   So don't favour the erasable_list _too_ much. */
 		DBG_GC(1, "Picking block from erasable_list to GC next\n");
 		nextlist = &c->erasable_list;
@@ -94,7 +95,7 @@
 		ERROR_MSG("Eep. ret->gc_node for block at %#08x is NULL\n", ret->offset);
 		BUG();
 	}
-	
+
 	/* Have we accidentally picked a clean block with wasted space ? */
 	if (ret->wasted_size) {
 		DBG_GC(1, "Converting wasted_size %#08x to dirty_size\n", ret->wasted_size);
@@ -131,7 +132,7 @@
 
 		/* We can't start doing GC yet. We haven't finished checking
 		   the node CRCs etc. Do it now. */
-		
+
 		/* checked_ino is protected by the alloc_sem */
 		if (c->checked_ino > c->highest_ino) {
 			ERROR_MSG("Checked all inodes but still 0x%x bytes of unchecked space?\n",
@@ -173,7 +174,7 @@
 
 		case INO_STATE_READING:
 			/* We need to wait for it to finish, lest we move on
-			   and trigger the BUG() above while we haven't yet 
+			   and trigger the BUG() above while we haven't yet
 			   finished checking all its nodes */
 			DBG_GC(1, "Waiting for ino #%u to finish reading\n", ic->ino);
 			up(&c->alloc_sem);
@@ -215,7 +216,7 @@
 
 	DBG_GC(1, "GC from block %#08x, used_size %#08x, dirty_size %#08x, free_size %#08x\n",
 			jeb->offset, jeb->used_size, jeb->dirty_size, jeb->free_size);
-	
+
 	if (c->nextblock)
 		DBG_GC(1, "Nextblock at  %#08x, used_size %#08x, dirty_size %#08x, wasted_size %#08x, free_size %#08x\n",
 				c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size,
@@ -227,13 +228,13 @@
 	}
 
 	raw = jeb->gc_node;
-			
+
 	while(ref_obsolete(raw)) {
 		DBG_GC(1, "Node at %#08x is obsolete... skipping\n", ref_offset(raw));
 		raw = raw->next_phys;
 		if (unlikely(!raw)) {
 			ERROR_MSG("Eep. End of raw list while still supposedly nodes to GC\n");
-			ERROR_MSG("Erase block at %#08x. free_size %#08x, dirty_size %#08x, used_size %#08x\n", 
+			ERROR_MSG("Erase block at %#08x. free_size %#08x, dirty_size %#08x, used_size %#08x\n",
 				       jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size);
 			jeb->gc_node = raw;
 			spin_unlock(&c->erase_completion_lock);
@@ -258,7 +259,7 @@
 	ic = jffs3_raw_ref_to_ic(raw);
 
 	/* We need to hold the inocache. Either the erase_completion_lock or
-	   the inocache_lock are sufficient; we trade down since the inocache_lock 
+	   the inocache_lock are sufficient; we trade down since the inocache_lock
 	   causes less contention. */
 	spin_lock(&c->inocache_lock);
 
@@ -278,7 +279,7 @@
 
 	switch(ic->state) {
 	case INO_STATE_CHECKEDABSENT:
-		/* It's been checked, but it's not currently in-core. 
+		/* It's been checked, but it's not currently in-core.
 		   We can just copy any pristine nodes, but have
 		   to prevent anyone else from doing read_inode() while
 		   we're at it, so we set the state accordingly */
@@ -297,8 +298,8 @@
 	case INO_STATE_CHECKING:
 	case INO_STATE_GC:
 		/* Should never happen. We should have finished checking
-		   by the time we actually start doing any GC, and since 
-		   we're holding the alloc_sem, no other garbage collection 
+		   by the time we actually start doing any GC, and since
+		   we're holding the alloc_sem, no other garbage collection
 		   can happen.
 		*/
 		ERROR_MSG("Inode #%u already in state %d in jffs3_garbage_collect_pass()!\n",
@@ -317,21 +318,21 @@
 		up(&c->alloc_sem);
 		DBG_GC(1, "Waiting for ino #%u in state %d\n", ic->ino, ic->state);
 		sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
-		/* And because we dropped the alloc_sem we must start again from the 
+		/* And because we dropped the alloc_sem we must start again from the
 		   beginning. Ponder chance of livelock here -- we're returning success
 		   without actually making any progress.
 
-		   Q: What are the chances that the inode is back in INO_STATE_READING 
+		   Q: What are the chances that the inode is back in INO_STATE_READING
 		   again by the time we next enter this function? And that this happens
 		   enough times to cause a real delay?
 
-		   A: Small enough that I don't care :) 
+		   A: Small enough that I don't care :)
 		*/
 		return 0;
 	}
 
 	/* OK. Now if the inode is in state INO_STATE_GC, we are going to copy the
-	   node intact, and we don't have to muck about with the fragtree etc. 
+	   node intact, and we don't have to muck about with the fragtree etc.
 	   because we know it's not in-core. If it _was_ in-core, we go through
 	   all the iget() crap anyway */
 
@@ -451,7 +452,7 @@
 			if (!ret) {
 				/* Urgh. Return it sensibly. */
 				frag->node->raw = f->inocache->nodes;
-			}	
+			}
 			if (ret != -EBADFD)
 				goto upnout;
 		}
@@ -465,7 +466,7 @@
 		}
 		goto upnout;
 	}
-	
+
 	/* Wasn't a dnode. Try dirent */
 	for (fd = f->dents; fd; fd=fd->next) {
 		if (fd->raw == raw)
@@ -491,7 +492,7 @@
 	return ret;
 }
 
-static int jffs3_garbage_collect_pristine(struct jffs3_sb_info *c, 
+static int jffs3_garbage_collect_pristine(struct jffs3_sb_info *c,
 					  struct jffs3_inode_cache *ic,
 					  struct jffs3_raw_node_ref *raw)
 {
@@ -510,7 +511,7 @@
 	/* Ask for a small amount of space (or the totlen if smaller) because we
 	   don't want to force wastage of the end of a block if splitting would
 	   work. */
-	ret = jffs3_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs3_raw_inode) + JFFS3_MIN_DATA_LEN, 
+	ret = jffs3_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs3_raw_inode) + JFFS3_MIN_DATA_LEN,
 					      rawlen), &phys_ofs, &alloclen, rawlen); /* this is not optimal yet */
 	if (ret)
 		return ret;
@@ -574,7 +575,7 @@
 		}
 		break;
 	default:
-		WARNING_MSG("Unknown node type for REF_PRISTINE node at %#08x: 0x%04x\n", 
+		WARNING_MSG("Unknown node type for REF_PRISTINE node at %#08x: 0x%04x\n",
 		       ref_offset(raw), je16_to_cpu(node->u.nodetype));
 		goto bail;
 	}
@@ -588,7 +589,9 @@
 	/* OK, all the CRCs are good; this node can just be copied as-is. */
  retry:
 	nraw->flash_offset = phys_ofs;
+#ifdef TMP_TOTLEN
 	nraw->__totlen = rawlen;
+#endif
 	nraw->next_phys = NULL;
 
 	ret = jffs3_flash_write(c, phys_ofs, rawlen, &retlen, (char *)node);
@@ -601,7 +604,7 @@
 			nraw->next_in_ino = NULL;
 
 			nraw->flash_offset |= REF_OBSOLETE;
-			jffs3_add_physical_node_ref(c, nraw);
+			jffs3_add_physical_node_ref(c, nraw, rawlen);
 			jffs3_mark_node_obsolete(c, nraw);
 		} else {
 			WARNING_MSG("Not marking the space at %#08x as dirty because the flash "
@@ -616,7 +619,7 @@
 			retried = 1;
 
 			DBG_GC(1, "Retrying failed write of REF_PRISTINE node.\n");
-			
+
 			jffs3_dbg_acct_sanity_check(c, jeb);
 			if (PARANOIA)
 				jffs3_dbg_acct_paranoia_check(c, jeb);
@@ -642,7 +645,7 @@
 		goto out_node;
 	}
 	nraw->flash_offset |= REF_PRISTINE;
-	jffs3_add_physical_node_ref(c, nraw);
+	jffs3_add_physical_node_ref(c, nraw, rawlen);
 
 	/* Link into per-inode list. This is safe because of the ic
 	   state being INO_STATE_GC. Note that if we're doing this
@@ -664,7 +667,7 @@
 	goto out_node;
 }
 
-static int jffs3_garbage_collect_metadata(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb, 
+static int jffs3_garbage_collect_metadata(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb,
 					struct jffs3_inode_info *f, struct jffs3_full_dnode *fn)
 {
 	struct jffs3_full_dnode *new_fn;
@@ -678,7 +681,7 @@
 	    S_ISCHR(JFFS3_F_I_MODE(f)) ) {
 		/* For these, we don't actually need to read the old node */
 		/* FIXME: for minor or major > 255. */
-		dev = cpu_to_je16(((JFFS3_F_I_RDEV_MAJ(f) << 8) | 
+		dev = cpu_to_je16(((JFFS3_F_I_RDEV_MAJ(f) << 8) |
 			JFFS3_F_I_RDEV_MIN(f)));
 		mdata = (char *)&dev;
 		mdatalen = sizeof(dev);
@@ -699,14 +702,14 @@
 		DBG_GC(1, "Writing %d bites of symlink target\n", mdatalen);
 
 	}
-	
+
 	ret = jffs3_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen, JFFS3_SUMMARY_INODE_SIZE);
 	if (ret) {
 		WARNING_MSG("Reserve space of %zd bytes for garbage_collect_metadata failed: %d\n",
 		       sizeof(ri)+ mdatalen, ret);
 		goto out;
 	}
-	
+
 	memset(&ri, 0, sizeof(ri));
 	ri.magic = cpu_to_je16(JFFS3_MAGIC_BITMASK);
 	ri.nodetype = cpu_to_je16(JFFS3_NODETYPE_INODE);
@@ -745,7 +748,7 @@
 	return ret;
 }
 
-static int jffs3_garbage_collect_dirent(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb, 
+static int jffs3_garbage_collect_dirent(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb,
 					struct jffs3_inode_info *f, struct jffs3_full_dirent *fd)
 {
 	struct jffs3_full_dirent *new_fd;
@@ -766,7 +769,7 @@
 	rd.type = fd->type;
 	rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8));
 	rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize));
-	
+
 	ret = jffs3_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen, JFFS3_SUMMARY_DIRENT_SIZE(rd.nsize));
 	if (ret) {
 		WARNING_MSG("Reserve space of %zd bytes for garbage_collect_dirent failed: %d\n",
@@ -783,7 +786,7 @@
 	return 0;
 }
 
-static int jffs3_garbage_collect_deletion_dirent(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb, 
+static int jffs3_garbage_collect_deletion_dirent(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb,
 					struct jffs3_inode_info *f, struct jffs3_full_dirent *fd)
 {
 	struct jffs3_full_dirent **fdp = &f->dents;
@@ -822,7 +825,7 @@
 			if (ref_totlen(c, NULL, raw) != rawlen)
 				continue;
 
-			/* Doesn't matter if there's one in the same erase block. We're going to 
+			/* 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)))
@@ -904,13 +907,13 @@
 
 	DBG_GC(1, "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n",
 		f->inocache->ino, start, end);
-	
+
 	memset(&ri, 0, sizeof(ri));
 
 	if(fn->frags > 1) {
 		size_t readlen;
 		uint32_t crc;
-		/* It's partially obsoleted by a later write. So we have to 
+		/* It's partially obsoleted by a later write. So we have to
 		   write it out again with the _same_ version as before */
 		ret = jffs3_flash_read(c, ref_offset(fn->raw), sizeof(ri), &readlen, (char *)&ri);
 		if (readlen != sizeof(ri) || ret) {
@@ -933,13 +936,13 @@
 			WARNING_MSG("Node at %#08x had CRC %#08x which doesn't match calculated CRC %#08x\n",
 				       ref_offset(fn->raw), je32_to_cpu(ri.node_crc), crc);
 			/* FIXME: We could possibly deal with this by writing new holes for each frag */
-			WARNING_MSG("Data in the range %#08x to %#08x of inode #%u will be lost\n", 
+			WARNING_MSG("Data in the range %#08x to %#08x of inode #%u will be lost\n",
 				       start, end, f->inocache->ino);
 			goto fill;
 		}
 		if (ri.compr != JFFS3_COMPR_ZERO) {
 			WARNING_MSG("Node %#08x wasn't a hole node!\n", ref_offset(fn->raw));
-			WARNING_MSG("Data in the range %#08x to %#08x of inode #%u will be lost\n", 
+			WARNING_MSG("Data in the range %#08x to %#08x of inode #%u will be lost\n",
 					       start, end, f->inocache->ino);
 			goto fill;
 		}
@@ -989,17 +992,17 @@
 		return 0;
 	}
 
-	/* 
+	/*
 	 * We should only get here in the case where the node we are
 	 * replacing had more than one frag, so we kept the same version
-	 * number as before. (Except in case of error -- see 'goto fill;' 
+	 * number as before. (Except in case of error -- see 'goto fill;'
 	 * above.)
 	 */
 
 	/* This is a partially-overlapped hole node. Mark it REF_NORMAL not REF_PRISTINE */
 	mark_ref_normal(new_fn->raw);
 
-	for (frag = jffs3_lookup_node_frag(&f->fragtree, fn->ofs); 
+	for (frag = jffs3_lookup_node_frag(&f->fragtree, fn->ofs);
 	     frag; frag = frag_next(frag)) {
 		if (frag->ofs > fn->size + fn->ofs)
 			break;
@@ -1017,10 +1020,10 @@
 		ERROR_MSG("New node has no frags!\n");
 		BUG();
 	}
-		
+
 	jffs3_mark_node_obsolete(c, fn->raw);
 	jffs3_free_full_dnode(fn);
-	
+
 	return 0;
 }
 
@@ -1030,12 +1033,12 @@
 {
 	struct jffs3_full_dnode *new_fn;
 	struct jffs3_raw_inode ri;
-	uint32_t alloclen, phys_ofs, offset, orig_end, orig_start;	
+	uint32_t alloclen, phys_ofs, offset, orig_end, orig_start;
 	int ret = 0;
 	unsigned char *comprbuf = NULL, *writebuf;
 	unsigned long pg;
 	unsigned char *pg_ptr;
- 
+
 	memset(&ri, 0, sizeof(ri));
 
 	DBG_GC(1, "Writing replacement dnode for ino #%u from offset 0x%x to 0x%x\n",
@@ -1047,8 +1050,8 @@
 	if (c->nr_free_blocks + c->nr_erasing_blocks > c->resv_blocks_gcmerge) {
 		/* Attempt to do some merging. But only expand to cover logically
 		   adjacent frags if the block containing them is already considered
-		   to be dirty. Otherwise we end up with GC just going round in 
-		   circles dirtying the nodes it already wrote out, especially 
+		   to be dirty. Otherwise we end up with GC just going round in
+		   circles dirtying the nodes it already wrote out, especially
 		   on NAND where we have small eraseblocks and hence a much higher
 		   chance of nodes having to be split to cross boundaries. */
 
@@ -1082,7 +1085,7 @@
 				break;
 			} else {
 
-				/* OK, it's a frag which extends to the beginning of the page. Does it live 
+				/* OK, it's a frag which extends to the beginning of the page. Does it live
 				   in a block which is still considered clean? If so, don't obsolete it.
 				   If not, cover it anyway. */
 
@@ -1132,7 +1135,7 @@
 				break;
 			} else {
 
-				/* OK, it's a frag which extends to the beginning of the page. Does it live 
+				/* OK, it's a frag which extends to the beginning of the page. Does it live
 				   in a block which is still considered clean? If so, don't obsolete it.
 				   If not, cover it anyway. */
 
@@ -1159,14 +1162,14 @@
 				break;
 			}
 		}
-		DBG_GC(1, "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n", 
+		DBG_GC(1, "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n",
 			  orig_start, orig_end, start, end);
 
 		BUG_ON(end > JFFS3_F_I_SIZE(f));
 		BUG_ON(end < orig_end);
 		BUG_ON(start > orig_start);
 	}
-	
+
 	/* First, use readpage() to read the appropriate page into the page cache */
 	/* Q: What happens if we actually try to GC the _same_ page for which commit_write()
 	 *    triggered garbage collection in the first place?
@@ -1222,7 +1225,7 @@
 		ri.usercompr = (comprtype >> 8) & 0xff;
 		ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
 		ri.data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
-	
+
 		new_fn = jffs3_write_dnode(c, f, &ri, comprbuf, cdatalen, phys_ofs, ALLOC_GC);
 
 		jffs3_free_comprbuf(comprbuf, writebuf);

Index: histo.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/histo.h,v
retrieving revision 3.1
retrieving revision 3.2
diff -u -r3.1 -r3.2
--- histo.h	9 Dec 2004 16:05:05 -0000	3.1
+++ histo.h	25 Dec 2004 11:11:21 -0000	3.2
@@ -1,3 +1,3 @@
 /* This file provides the bit-probabilities for the input file */
-#define BIT_DIVIDER 629 
+#define BIT_DIVIDER 629
 static int bits[9] = { 179,167,183,165,159,198,178,119,}; /* ia32 .so files */

Index: histo_mips.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/histo_mips.h,v
retrieving revision 3.1
retrieving revision 3.2
diff -u -r3.1 -r3.2
--- histo_mips.h	9 Dec 2004 16:05:05 -0000	3.1
+++ histo_mips.h	25 Dec 2004 11:11:21 -0000	3.2
@@ -1,2 +1,2 @@
-#define BIT_DIVIDER_MIPS 1043 
+#define BIT_DIVIDER_MIPS 1043
 static int bits_mips[8] = { 277,249,290,267,229,341,212,241}; /* mips32 */

Index: ioctl.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/ioctl.c,v
retrieving revision 3.1
retrieving revision 3.2
diff -u -r3.1 -r3.2
--- ioctl.c	9 Dec 2004 16:05:05 -0000	3.1
+++ ioctl.c	25 Dec 2004 11:11:21 -0000	3.2
@@ -14,11 +14,11 @@
 
 #include <linux/fs.h>
 
-int jffs3_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 
+int jffs3_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
 		unsigned long arg)
 {
 	/* Later, this will provide for lsattr.jffs3 and chattr.jffs3, which
 	   will include compression support etc. */
 	return -ENOTTY;
 }
-	
+

Index: jffs3.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/jffs3.h,v
retrieving revision 3.4
retrieving revision 3.5
diff -u -r3.4 -r3.5
--- jffs3.h	21 Dec 2004 15:18:50 -0000	3.4
+++ jffs3.h	25 Dec 2004 11:11:21 -0000	3.5
@@ -5,7 +5,7 @@
  *
  * Created by David Woodhouse <dwmw2 at infradead.org>
  *
- * For licensing information, see the file 'LICENCE' in the 
+ * For licensing information, see the file 'LICENCE' in the
  * jffs3 directory.
  *
  * $Id$
@@ -26,10 +26,10 @@
 #include <asm/semaphore.h>
 #include <linux/rwsem.h>
 
-/* 
- * You must include something which defines the C99 uintXX_t types. 
+/*
+ * You must include something which defines the C99 uintXX_t types.
  *  We don't do it from here because this file is used in too many
- * different environments. 
+ * different environments.
  */
 
 #define JFFS3_SUPER_MAGIC 0x72b6
@@ -42,11 +42,11 @@
 #define JFFS3_DIRTY_BITMASK 0x0000
 
 /* Summary node MAGIC marker */
-#define JFFS3_SUM_MAGIC	0x02851885 
+#define JFFS3_SUM_MAGIC	0x02851885
 
-/* 
+/*
  * We only allow a single char for length, and 0xFF is empty flash so
- *  we don't want it confused with a real length. Hence max 254. 
+ *  we don't want it confused with a real length. Hence max 254.
  */
 #define JFFS3_MAX_NAME_LEN 254
 
@@ -127,9 +127,9 @@
 	uint8_t name[0];
 } __attribute__((packed));
 
-/* 
+/*
  * The JFFS3 raw inode structure: Used for storage on physical media.
- * The uid, gid, atime, mtime and ctime members could be longer, but 
+ * The uid, gid, atime, mtime and ctime members could be longer, but
  * are left like this for space efficiency. If and when people decide
  * they really need them extended, it's simple enough to add support for
  * a new type of raw node.
@@ -161,13 +161,13 @@
 } __attribute__((packed));
 
 struct jffs3_summary_node{
-    jint16_t magic;
+	jint16_t magic;
 	jint16_t nodetype; 	/* = JFFS3_NODETYPE_INODE_SUM */
 	jint32_t totlen;
 	jint32_t hdr_crc;
 	jint16_t sum_num;	/* number of sum entries*/
 	jint32_t cln_mkr;	/* clean marker size, 0 = no cleanmarker */
-    jint32_t padded;        /* sum of the size of padding nodes */
+	jint32_t padded;        /* sum of the size of padding nodes */
 	jint32_t sum_crc;	/* summary information crc */
 	jint32_t node_crc; 	/* node crc */
 	jint32_t sum[0]; 	/* inode summary info */
@@ -198,7 +198,7 @@
 
 	/* There may be one datanode which isn't referenced by any of the
 	   above fragments, if it contains a metadata update but no actual
-	   data - or if this is a directory inode. 
+	   data - or if this is a directory inode.
 	   This also holds the _only_ dnode for symlinks/device nodes, etc. */
 	struct jffs3_full_dnode *metadata;
 
@@ -216,7 +216,7 @@
 
 struct jffs3_inodirty;
 
-/* 
+/*
  * A struct for the overall file system control. Pointers to
  * jffs3_sb_info structs are named `c' in the source code.
  */
@@ -232,7 +232,7 @@
 	struct semaphore gc_thread_start;	/* GC thread start mutex */
 	struct completion gc_thread_exit;	/* GC thread exit completion port */
 
-	struct semaphore alloc_sem;	/* Used to protect all the following 
+	struct semaphore alloc_sem;	/* Used to protect all the following
 					   fields, and also to protect against
 					   out-of-order writing of nodes. And GC. */
 	uint32_t cleanmarker_size;	/* Size of an _inline_ CLEANMARKER
@@ -261,7 +261,7 @@
 	uint32_t nospc_dirty_size;
 
 	uint32_t nr_blocks;
-	struct jffs3_eraseblock *blocks;	/* The whole array of blocks. Used for getting blocks 
+	struct jffs3_eraseblock *blocks;	/* The whole array of blocks. Used for getting blocks
 						 * from the offset (blocks[ofs / sector_size]) */
 	struct jffs3_eraseblock *nextblock;	/* The block we're currently filling */
 
@@ -280,16 +280,16 @@
 	struct list_head bad_list;		/* Bad blocks. */
 	struct list_head bad_used_list;		/* Bad blocks with valid data in. */
 
-	spinlock_t erase_completion_lock;	/* Protect free_list and erasing_list 
+	spinlock_t erase_completion_lock;	/* Protect free_list and erasing_list
 						   against erase completion handler */
 	wait_queue_head_t erase_wait;		/* For waiting for erases to complete */
 
 	wait_queue_head_t inocache_wq;
 	struct jffs3_inode_cache **inocache_list;
 	spinlock_t inocache_lock;
-	
+
 	/* Semaphore to allow jffs3_garbage_collect_deletion_dirent to
-	   drop the erase_completion_lock while it's holding a pointer 
+	   drop the erase_completion_lock while it's holding a pointer
 	   to an obsoleted node. I don't like this. Alternatives welcomed. */
 	struct semaphore erase_free_sem;
 
@@ -301,7 +301,7 @@
 	uint32_t wbuf_pagesize;
 	struct jffs3_inodirty *wbuf_inodes;
 	struct rw_semaphore wbuf_sem;	/* Protects the write buffer */
-	
+
 	/* Information about out-of-band area usage... */
 	struct nand_oobinfo *oobinfo;
 	uint32_t badblock_pos;
@@ -310,7 +310,7 @@
 #endif
 #ifdef CONFIG_JFFS3_SUMMARY
     jint32_t *summary_buf;
-#endif	
+#endif
 
 	/* OS-private pointer for getting back to master superblock info */
 	void *os_priv;

Index: malloc.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/malloc.c,v
retrieving revision 3.4
retrieving revision 3.5
diff -u -r3.4 -r3.5
--- malloc.c	17 Dec 2004 18:04:57 -0000	3.4
+++ malloc.c	25 Dec 2004 11:11:21 -0000	3.5
@@ -32,7 +32,7 @@
 
 int __init jffs3_create_slab_caches(void)
 {
-	full_dnode_slab = kmem_cache_create("jffs3_full_dnode", 
+	full_dnode_slab = kmem_cache_create("jffs3_full_dnode",
 					    sizeof(struct jffs3_full_dnode),
 					    0, JFFS3_SLAB_POISON, NULL, NULL);
 	if (!full_dnode_slab)

Index: nodelist.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/nodelist.c,v
retrieving revision 3.3
retrieving revision 3.4
diff -u -r3.3 -r3.4
--- nodelist.c	23 Dec 2004 18:53:36 -0000	3.3
+++ nodelist.c	25 Dec 2004 11:11:21 -0000	3.4
@@ -50,25 +50,25 @@
 	new->next = *prev;
 	*prev = new;
 
- out:
+out:
 	if (DEBUG2) {
-		DBG_BI(2, "Direntries list:\n");
-		jffs3_dbg_print_dirents_list(*list);
+		DBG_BI(2, "Direntries list dump:\n");
+		jffs3_dbg_dump_dirents_list(*list);
 	}
 }
 
-/* Put a new tmp_dnode_info into the list, keeping the list in 
+/* Put a new tmp_dnode_info into the list, keeping the list in
    order of increasing version
 */
 static void jffs3_add_tn_to_list(struct jffs3_tmp_dnode_info *tn, struct jffs3_tmp_dnode_info **list)
 {
 	struct jffs3_tmp_dnode_info **prev = list;
-	
+
 	while ((*prev) && (*prev)->version < tn->version) {
 		prev = &((*prev)->next);
 	}
 	tn->next = (*prev);
-        *prev = tn;
+	*prev = tn;
 }
 
 static void jffs3_free_tmp_dnode_info_list(struct jffs3_tmp_dnode_info *tn)
@@ -122,14 +122,16 @@
 	int err;
 
 	*mctime_ver = 0;
-	
-	DBG_RI(1, "ino #%u\n", f->inocache->ino);
+
+	DBG_RI(1, "Read ino #%u, nlink %d, state %d\n",
+		f->inocache->ino, f->inocache->nlink,
+		f->inocache->state);
 
 	spin_lock(&c->erase_completion_lock);
 
 	valid_ref = jffs3_first_valid_node(f->inocache->nodes);
 
-	if (!valid_ref && f->inocache->ino != 0)
+	if (!valid_ref && f->inocache->ino != 1)
 		WARNING_MSG("Eep. No valid nodes for ino #%u\n", f->inocache->ino);
 
 	while (valid_ref) {
@@ -146,7 +148,7 @@
 		cond_resched();
 
 		/* FIXME: point() */
-		err = jffs3_flash_read(c, (ref_offset(ref)), 
+		err = jffs3_flash_read(c, (ref_offset(ref)),
 				       min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node)),
 				       &retlen, (void *)&node);
 		if (err) {
@@ -154,7 +156,7 @@
 						err, ref_offset(ref));
 			goto free_out;
 		}
-			
+
 
 			/* Check we've managed to read at least the common node header */
 		if (retlen < min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node.u))) {
@@ -162,7 +164,7 @@
 			err = -EIO;
 			goto free_out;
 		}
-			
+
 		switch (je16_to_cpu(node.u.nodetype)) {
 		case JFFS3_NODETYPE_DIRENT:
 			DBG_RI(1, "Node at %08x (%d) is a dirent node\n", ref_offset(ref), ref_flags(ref));
@@ -191,7 +193,7 @@
 				       ref_offset(ref));
 				BUG();
 			}
-			
+
 			fd = jffs3_alloc_full_dirent(node.d.nsize+1);
 			if (!fd) {
 				err = -ENOMEM;
@@ -213,19 +215,19 @@
 			*/
 			if (retlen > sizeof(struct jffs3_raw_dirent))
 				memcpy(&fd->name[0], &node.d.name[0], min_t(uint32_t, node.d.nsize, (retlen-sizeof(struct jffs3_raw_dirent))));
-				
+
 			/* Do we need to copy any more of the name directly
 			   from the flash?
 			*/
 			if (node.d.nsize + sizeof(struct jffs3_raw_dirent) > retlen) {
 				/* FIXME: point() */
 				int already = retlen - sizeof(struct jffs3_raw_dirent);
-					
-				err = jffs3_flash_read(c, (ref_offset(ref)) + retlen, 
+
+				err = jffs3_flash_read(c, (ref_offset(ref)) + retlen,
 						   node.d.nsize - already, &retlen, &fd->name[already]);
 				if (!err && retlen != node.d.nsize - already)
 					err = -EIO;
-					
+
 				if (err) {
 					WARNING_MSG("Read remainder of name in jffs3_get_inode_nodes(): error %d\n", err);
 					jffs3_free_full_dirent(fd);
@@ -236,7 +238,7 @@
 			fd->next = NULL;
 			fd->name[node.d.nsize] = '\0';
 				/* Wheee. We now have a complete jffs3_full_dirent structure, with
-				   the name in it and everything. Link it into the list 
+				   the name in it and everything. Link it into the list
 				*/
 			DBG_RI(1, "Adding fd \"%s\", ino #%u\n", fd->name, fd->ino);
 			jffs3_add_fd_to_list(c, fd, &ret_fd);
@@ -274,7 +276,7 @@
 					spin_lock(&c->erase_completion_lock);
 					continue;
 				}
-				
+
 				/* sanity checks */
 				if ( je32_to_cpu(node.i.offset) > je32_to_cpu(node.i.isize) ||
 					PAD(je32_to_cpu(node.i.csize) + sizeof (node.i))
@@ -282,7 +284,7 @@
 					WARNING_MSG("Inode corrupted at 0x%08x, totlen %d, #ino  %d, "
 						"version %d, isize %d, csize %d, dsize %d \n",
 						ref_offset(ref),  je32_to_cpu(node.i.totlen),  je32_to_cpu(node.i.ino),
-						je32_to_cpu(node.i.version),  je32_to_cpu(node.i.isize), 
+						je32_to_cpu(node.i.version),  je32_to_cpu(node.i.isize),
 						je32_to_cpu(node.i.csize), je32_to_cpu(node.i.dsize));
 					jffs3_mark_node_obsolete(c, ref);
 					spin_lock(&c->erase_completion_lock);
@@ -304,12 +306,12 @@
 						} else
 							pointed = 1; /* succefully pointed to device */
 					}
-#endif					
+#endif
 					if(!pointed){
 						buf = kmalloc(je32_to_cpu(node.i.csize), GFP_KERNEL);
 						if (!buf)
 							return -ENOMEM;
-						
+
 						err = jffs3_flash_read(c, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize),
 								       &retlen, buf);
 						if (!err && retlen != je32_to_cpu(node.i.csize))
@@ -335,7 +337,7 @@
 						spin_lock(&c->erase_completion_lock);
 						continue;
 					}
-					
+
 				}
 
 				/* Mark the node as having been checked and fix the accounting accordingly */
@@ -348,12 +350,12 @@
 				c->used_size += len;
 				c->unchecked_size -= len;
 
-				/* If node covers at least a whole page, or if it starts at the 
-				   beginning of a page and runs to the end of the file, or if 
-				   it's a hole node, mark it REF_PRISTINE, else REF_NORMAL. 
+				/* If node covers at least a whole page, or if it starts at the
+				   beginning of a page and runs to the end of the file, or if
+				   it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
 
-				   If it's actually overlapped, it'll get made NORMAL (or OBSOLETE) 
-				   when the overlapping node(s) get added to the tree anyway. 
+				   If it's actually overlapped, it'll get made NORMAL (or OBSOLETE)
+				   when the overlapping node(s) get added to the tree anyway.
 				*/
 				if ((je32_to_cpu(node.i.dsize) >= PAGE_CACHE_SIZE) ||
 				    ( ((je32_to_cpu(node.i.offset)&(PAGE_CACHE_SIZE-1))==0) &&
@@ -422,7 +424,7 @@
 				/* Hmmm. This should have been caught at scan time. */
 				WARNING_MSG("Node header CRC failed at %08x. But it must have been OK earlier.\n",
 				       ref_offset(ref));
-				WARNING_MSG("Node was: { %04x, %04x, %08x, %08x }\n", 
+				WARNING_MSG("Node was: { %04x, %04x, %08x, %08x }\n",
 				       je16_to_cpu(node.u.magic), je16_to_cpu(node.u.nodetype), je32_to_cpu(node.u.totlen),
 				       je32_to_cpu(node.u.hdr_crc));
 				jffs3_mark_node_obsolete(c, ref);
@@ -439,7 +441,7 @@
 				if (!(c->flags & JFFS3_SB_FLAG_RO))
 					BUG();
 				break;
-			case JFFS3_FEATURE_RWCOMPAT_COPY:				
+			case JFFS3_FEATURE_RWCOMPAT_COPY:
 				DBG_RI(1, "Unknown RWCOMPAT_COPY nodetype %04X at %08x\n",
 					je16_to_cpu(node.u.nodetype), ref_offset(ref));
 				break;
@@ -460,7 +462,7 @@
 
 	return 0;
 
- free_out:
+free_out:
 	jffs3_free_tmp_dnode_info_list(ret_tn);
 	jffs3_free_full_dirent_list(ret_fd);
 	return err;
@@ -476,33 +478,43 @@
 
 /* During mount, this needs no locking. During normal operation, its
    callers want to do other stuff while still holding the inocache_lock.
-   Rather than introducing special case get_ino_cache functions or 
+   Rather than introducing special case get_ino_cache functions or
    callbacks, we just let the caller do the locking itself. */
-   
+
 struct jffs3_inode_cache *jffs3_get_ino_cache(struct jffs3_sb_info *c, uint32_t ino)
 {
 	struct jffs3_inode_cache *ret;
 
-	DBG(1, "ino %u\n", ino);
+	DBG(1, "Searching jffs3_inode_cache object for ino %u\n", ino);
 
 	ret = c->inocache_list[ino % INOCACHE_HASHSIZE];
 	while (ret && ret->ino < ino) {
 		ret = ret->next;
 	}
-	
+
 	if (ret && ret->ino != ino)
 		ret = NULL;
 
-	DBG(1, "found %p for ino %u\n", ret, ino);
+	if (DEBUG1) {
+		if (ret != NULL)
+			DBG(1, "Found %p\n", ret);
+		else
+			DBG(1, "Not found\n");
+	}
+
 	return ret;
 }
 
 void jffs3_add_ino_cache (struct jffs3_sb_info *c, struct jffs3_inode_cache *new)
 {
 	struct jffs3_inode_cache **prev;
-	DBG(2, "Add %p (ino #%u)\n", new, new->ino);
+
+	DBG(2, "Add jffs3_inode_cache object (%p) for ino #%u\n", new, new->ino);
+	if (SANITY)
+		BUG_ON(new->ino == 0);
+
 	spin_lock(&c->inocache_lock);
-	
+
 	prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE];
 
 	while ((*prev) && (*prev)->ino < new->ino) {
@@ -519,9 +531,9 @@
 	struct jffs3_inode_cache **prev;
 	DBG(2, "Del %p (ino #%u)\n", old, old->ino);
 	spin_lock(&c->inocache_lock);
-	
+
 	prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE];
-	
+
 	while ((*prev) && (*prev)->ino < old->ino) {
 		prev = &(*prev)->next;
 	}
@@ -536,7 +548,7 @@
 {
 	int i;
 	struct jffs3_inode_cache *this, *next;
-	
+
 	for (i=0; i<INOCACHE_HASHSIZE; i++) {
 		this = c->inocache_list[i];
 		while (this) {
@@ -564,10 +576,10 @@
 		c->blocks[i].first_node = c->blocks[i].last_node = NULL;
 	}
 }
-	
+
 struct jffs3_node_frag *jffs3_lookup_node_frag(struct rb_root *fragtree, uint32_t offset)
 {
-	/* The common case in lookup is that there will be a node 
+	/* The common case in lookup is that there will be a node
 	   which precisely matches. So we go looking for that first */
 	struct rb_node *next;
 	struct jffs3_node_frag *prev = NULL;
@@ -606,9 +618,9 @@
 	if (prev)
 		DBG_BI(2, "No match. Returning frag %d,%d, closest previous\n",
 			  prev->ofs, prev->ofs+prev->size);
-	else 
+	else
 		DBG_BI(2, "Returning NULL, empty fragtree\n");
-	
+
 	return prev;
 }
 
@@ -626,13 +638,13 @@
 
 	while(frag) {
 		if (frag->rb.rb_left) {
-			DBG_BI(2, "Going left from frag (%p) %d-%d\n", 
+			DBG_BI(2, "Going left from frag (%p) %d-%d\n",
 				  frag, frag->ofs, frag->ofs+frag->size);
 			frag = frag_left(frag);
 			continue;
 		}
 		if (frag->rb.rb_right) {
-			DBG_BI(2, "Going right from frag (%p) %d-%d\n", 
+			DBG_BI(2, "Going right from frag (%p) %d-%d\n",
 				  frag, frag->ofs, frag->ofs+frag->size);
 			frag = frag_right(frag);
 			continue;
@@ -641,20 +653,20 @@
 		DBG_BI(2, "frag at 0x%x-0x%x: node %p, frags %d--\n",
 			  frag->ofs, frag->ofs+frag->size, frag->node,
 			  frag->node?frag->node->frags:0);
-			
+
 		if (frag->node && !(--frag->node->frags)) {
-			/* Not a hole, and it's the final remaining frag 
+			/* Not a hole, and it's the final remaining frag
 			   of this node. Free the node */
 			if (c)
 				jffs3_mark_node_obsolete(c, frag->node->raw);
-			
+
 			jffs3_free_full_dnode(frag->node);
 		}
 		parent = frag_parent(frag);
 		if (parent) {
 			if (frag_left(parent) == frag)
 				parent->rb.rb_left = NULL;
-			else 
+			else
 				parent->rb.rb_right = NULL;
 		}
 
@@ -670,13 +682,13 @@
 	struct rb_node *parent = &base->rb;
 	struct rb_node **link = &parent;
 
-	DBG_BI(2, "newfrag %p frag range %d-%d, base %p)\n", newfrag, 
+	DBG_BI(2, "newfrag %p frag range %d-%d, base %p)\n", newfrag,
 		  newfrag->ofs, newfrag->ofs+newfrag->size, base);
 
 	while (*link) {
 		parent = *link;
 		base = rb_entry(parent, struct jffs3_node_frag, rb);
-	
+
 		DBG_BI(2, "considering frag at 0x%x\n", base->ofs);
 		if (newfrag->ofs > base->ofs)
 			link = &base->rb.rb_right;

Index: nodelist.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/nodelist.h,v
retrieving revision 3.7
retrieving revision 3.8
diff -u -r3.7 -r3.8
--- nodelist.h	23 Dec 2004 18:53:37 -0000	3.7
+++ nodelist.h	25 Dec 2004 11:11:21 -0000	3.8
@@ -19,7 +19,6 @@
 #include <linux/fs.h>
 #include <linux/types.h>
 #include "jffs3.h"
-#include "summary.h"
 
 #ifdef __ECOS
 #include "os-ecos.h"
@@ -28,6 +27,13 @@
 #include "os-linux.h"
 #endif
 
+/*
+ * TODO: Temporary. When the __totlen field removing is completed, all #ifdefs
+ * with TMP_TOTLEN should go.
+ * Note: The summary stuff is currently broken with regards to __totlen.
+ */
+#define TMP_TOTLEN
+
 #define JFFS3_NATIVE_ENDIAN
 
 /* Note we handle mode bits conversion from JFFS3 (i.e. Linux) to/from
@@ -57,14 +63,14 @@
 #define je16_to_cpu(x) (le16_to_cpu(x.v16))
 #define je32_to_cpu(x) (le32_to_cpu(x.v32))
 #define jemode_to_cpu(x) (le32_to_cpu(jffs3_to_os_mode((x).m)))
-#else 
+#else
 #error wibble
 #endif
 
 /*
   This is all we need to keep in-core for each raw node during normal
   operation. As and when we do read_inode on a particular inode, we can
-  scan the nodes which are listed for it and build up a proper map of 
+  scan the nodes which are listed for it and build up a proper map of
   which nodes are currently valid. JFFSv1 always used to keep that whole
   map in core for each inode.
 */
@@ -81,7 +87,7 @@
 
         /* flash_offset & 3 always has to be zero, because nodes are
 	   always aligned at 4 bytes. So we have a couple of extra bits
-	   to play with, which indicate the node's status; see below: */ 
+	   to play with, which indicate the node's status; see below: */
 #define REF_UNCHECKED	0	/* We haven't yet checked the CRC or built its inode */
 #define REF_OBSOLETE	1	/* Obsolete, can be completely ignored */
 #define REF_PRISTINE	2	/* Completely clean. GC without looking */
@@ -94,7 +100,7 @@
 /* For each inode in the filesystem, we need to keep a record of
    nlink, because it would be a PITA to scan the whole directory tree
    at read_inode() time to calculate it, and to keep sufficient information
-   in the raw_node_ref (basically both parent and child inode number for 
+   in the raw_node_ref (basically both parent and child inode number for
    dirent nodes) would take more space than this does. We also keep
    a pointer to the first physical node which is part of this inode, too.
 */
@@ -123,7 +129,7 @@
 #define INOCACHE_HASHSIZE 128
 
 /*
-  Larger representation of a raw node, kept in-core only when the 
+  Larger representation of a raw node, kept in-core only when the
   struct inode for this particular ino is instantiated.
 */
 
@@ -133,11 +139,11 @@
 	uint32_t ofs; /* The offset to which the data of this node belongs */
 	uint32_t size;
 	uint32_t frags; /* Number of fragments which currently refer
-			to this node. When this reaches zero, 
+			to this node. When this reaches zero,
 			the node is obsolete.  */
 };
 
-/* 
+/*
    Even larger representation of a raw node, kept in-core only while
    we're actually building up the original map of which nodes go where,
    in read_inode()
@@ -147,7 +153,7 @@
 	struct jffs3_tmp_dnode_info *next;
 	struct jffs3_full_dnode *fn;
 	uint32_t version;
-};       
+};
 
 struct jffs3_full_dirent
 {
@@ -161,7 +167,7 @@
 };
 
 /*
-  Fragments - used to build a map of which raw node to obtain 
+  Fragments - used to build a map of which raw node to obtain
   data from for each part of the ino
 */
 struct jffs3_node_frag
@@ -177,11 +183,11 @@
 	struct list_head list;
 	int bad_count;
 	uint32_t offset;		/* of this block in the MTD */
-	
-#ifdef CONFIG_JFFS3_SUMMARY	
+
+#ifdef CONFIG_JFFS3_SUMMARY
 	struct jffs3_sum_info *sum_collected;
 #endif
-	
+
 	uint32_t unchecked_size;
 	uint32_t used_size;
 	uint32_t dirty_size;
@@ -197,57 +203,55 @@
 #include "debug.h"
 
 /* Calculate totlen from surrounding nodes or eraseblock */
-static inline uint32_t __ref_totlen(struct jffs3_sb_info *c,
-				    struct jffs3_eraseblock *jeb,
-				    struct jffs3_raw_node_ref *ref)
+static inline uint32_t
+ref_totlen(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb,
+			struct jffs3_raw_node_ref *ref)
 {
 	uint32_t ref_end;
-	
+	uint32_t ref_offs = ref_offset(ref);
+
+	if (!jeb)
+		jeb = &c->blocks[ref->flash_offset / c->sector_size];
+
 	if (ref->next_phys)
 		ref_end = ref_offset(ref->next_phys);
 	else {
-		if (!jeb)
-			jeb = &c->blocks[ref->flash_offset / c->sector_size];
-
+#ifdef TMP_TOTLEN
+		if (ref != jeb->last_node) {
+			ERROR_MSG("ref %p, offset %#x, __totlen %u\n", ref, ref_offs, ref->__totlen);
+			ERROR_MSG("ref->next_phys is NULL, but this is not the last node for this block\n");
+			if (PARANOIA)
+				jffs3_dbg_dump_node_refs(c, jeb);
+			return ref->__totlen;
+		}
+#else
+		if (SANITY)
+			BUG_ON(ref != jeb->last_node);
+#endif
 		/* Last node in block. Use free_space */
-		BUG_ON(ref != jeb->last_node);
 		ref_end = jeb->offset + c->sector_size - jeb->free_size;
 	}
-	return ref_end - ref_offset(ref);
-}
-
-static inline uint32_t ref_totlen(struct jffs3_sb_info *c,
-				  struct jffs3_eraseblock *jeb,
-				  struct jffs3_raw_node_ref *ref)
-{
-	uint32_t ret;
 
 	if (PARANOIA && jeb && jeb != &c->blocks[ref->flash_offset / c->sector_size]) {
-		ERROR_MSG("ref_totlen called with wrong block -- at 0x%08x instead of 0x%08x; ref 0x%08x\n",
-		       jeb->offset, c->blocks[ref->flash_offset / c->sector_size].offset, ref_offset(ref));
+		ERROR_MSG("ref_totlen called with wrong block - %#08x instead of %#08x; ref 0x%08x\n",
+		       jeb->offset, c->blocks[ref->flash_offset / c->sector_size].offset, ref_offs);
 		BUG();
 	}
 
-#if 1
-	ret = ref->__totlen;
-#else
-	/* This doesn't actually work yet */
-	ret = __ref_totlen(c, jeb, ref);
-	if (ret != ref->__totlen) {
-		ERROR_MSG("Totlen for ref at %p (0x%08x-0x%08x) miscalculated as 0x%x instead of %x\n",
-		       ref, ref_offset(ref), ref_offset(ref)+ref->__totlen,
-		       ret, ref->__totlen);
-		if (!jeb)
-			jeb = &c->blocks[ref->flash_offset / c->sector_size];
-
-		jffs3_dbg_node_refs_dump(jeb);
-		BUG();
+#ifdef TMP_TOTLEN
+	if (ref_end - ref_offs != ref->__totlen) {
+		ERROR_MSG("Ref (%p) totlen %#x (%#08x-%#08x) miscalculated as "
+			"%#x (%#08x-%#08x) instead of %#x\n",
+			ref, ref->__totlen, ref_offs, ref_offs + ref->__totlen,
+			ref_end - ref_offs, ref_offs, ref_end, ref->__totlen);
+		if (PARANOIA)
+			jffs3_dbg_dump_node_refs(c, jeb);
 	}
+	return ref->__totlen;
 #endif
-	return ret;
+	return ref_end - ref_offs;
 }
 
-
 #define ALLOC_NORMAL	0	/* Normal allocation */
 #define ALLOC_DELETION	1	/* Deletion node. Best to allow it */
 #define ALLOC_GC	2	/* Space requested for GC. Give it or die */
@@ -257,7 +261,7 @@
 #define VERYDIRTY(c, size) ((size) >= ((c)->sector_size / 2))
 
 /* check if dirty space is more than 255 Byte */
-#define ISDIRTY(size) ((size) >  sizeof (struct jffs3_raw_inode) + JFFS3_MIN_DATA_LEN) 
+#define ISDIRTY(size) ((size) >  sizeof (struct jffs3_raw_inode) + JFFS3_MIN_DATA_LEN)
 
 #define PAD(x) (((x)+3)&~3)
 
@@ -311,7 +315,7 @@
 int jffs3_thread_should_wake(struct jffs3_sb_info *c);
 int jffs3_reserve_space(struct jffs3_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio, uint32_t sumsize);
 int jffs3_reserve_space_gc(struct jffs3_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, uint32_t sumsize);
-int jffs3_add_physical_node_ref(struct jffs3_sb_info *c, struct jffs3_raw_node_ref *new);
+int jffs3_add_physical_node_ref(struct jffs3_sb_info *c, struct jffs3_raw_node_ref *new, uint32_t len);
 void jffs3_complete_reservation(struct jffs3_sb_info *c);
 void jffs3_mark_node_obsolete(struct jffs3_sb_info *c, struct jffs3_raw_node_ref *raw);
 
@@ -321,7 +325,7 @@
 struct jffs3_full_dnode *jffs3_write_dnode(struct jffs3_sb_info *c, struct jffs3_inode_info *f, struct jffs3_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode);
 struct jffs3_full_dirent *jffs3_write_dirent(struct jffs3_sb_info *c, struct jffs3_inode_info *f, struct jffs3_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode);
 int jffs3_write_inode_range(struct jffs3_sb_info *c, struct jffs3_inode_info *f,
-			    struct jffs3_raw_inode *ri, unsigned char *buf, 
+			    struct jffs3_raw_inode *ri, unsigned char *buf,
 			    uint32_t offset, uint32_t writelen, uint32_t *retlen);
 int jffs3_do_create(struct jffs3_sb_info *c, struct jffs3_inode_info *dir_f, struct jffs3_inode_info *f, struct jffs3_raw_inode *ri, const char *name, int namelen);
 int jffs3_do_unlink(struct jffs3_sb_info *c, struct jffs3_inode_info *dir_f, const char *name, int namelen, struct jffs3_inode_info *dead_f);
@@ -331,7 +335,7 @@
 /* readinode.c */
 void jffs3_truncate_fraglist (struct jffs3_sb_info *c, struct rb_root *list, uint32_t size);
 int jffs3_add_full_dnode_to_inode(struct jffs3_sb_info *c, struct jffs3_inode_info *f, struct jffs3_full_dnode *fn);
-int jffs3_do_read_inode(struct jffs3_sb_info *c, struct jffs3_inode_info *f, 
+int jffs3_do_read_inode(struct jffs3_sb_info *c, struct jffs3_inode_info *f,
 			uint32_t ino, struct jffs3_raw_inode *latest_node);
 int jffs3_do_crccheck_inode(struct jffs3_sb_info *c, struct jffs3_inode_cache *ic);
 void jffs3_do_clear_inode(struct jffs3_sb_info *c, struct jffs3_inode_info *f);

Index: nodemgmt.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/nodemgmt.c,v
retrieving revision 3.6
retrieving revision 3.7
diff -u -r3.6 -r3.7
--- nodemgmt.c	23 Dec 2004 18:53:37 -0000	3.6
+++ nodemgmt.c	25 Dec 2004 11:11:21 -0000	3.7
@@ -50,8 +50,7 @@
 
 	DBG_RSV(1, "Requested 0x%x bytes\n", minsize);
 	down(&c->alloc_sem);
-
-	DBG_RSV(1, "jffs3_reserve_space(): alloc sem got\n");
+	DBG_RSV(1, "Alloc sem got\n");
 
 	spin_lock(&c->erase_completion_lock);
 
@@ -87,12 +86,12 @@
 				up(&c->alloc_sem);
 				return -ENOSPC;
 			}
-			
+
 			/* Calc possibly available space. Possibly available means that we
 			 * don't know, if unchecked size contains obsoleted nodes, which could give us some
 			 * more usable space. This will affect the sum only once, as gc first finishes checking
 			 * of nodes.
-			 + Return -ENOSPC, if the maximum possibly available space is less or equal than 
+			 + Return -ENOSPC, if the maximum possibly available space is less or equal than
 			 * blocksneeded * sector_size.
 			 * This blocks endless gc looping on a filesystem, which is nearly full, even if
 			 * the check above passes.
@@ -105,7 +104,7 @@
 					break;
 				}
 
-				DBG_RSV(1, "max. available size 0x%08x  < blocksneeded * sector_size "
+				DBG_RSV(1, "Max. available size 0x%08x  < blocksneeded * sector_size "
 					"0x%08x, returning -ENOSPC\n",
 					avail, blocksneeded * c->sector_size);
 				spin_unlock(&c->erase_completion_lock);
@@ -124,7 +123,7 @@
 					c->bad_size, c->free_size + c->dirty_size + c->wasted_size
 					 + c->used_size + c->erasing_size + c->bad_size, c->flash_size);
 			spin_unlock(&c->erase_completion_lock);
-			
+
 			ret = jffs3_garbage_collect_pass(c);
 			if (ret)
 				return ret;
@@ -140,7 +139,7 @@
 
 		ret = jffs3_do_reserve_space(c, minsize, ofs, len, sumsize);
 		if (ret) {
-			DBG_RSV(1, "ret is %d\n", ret);
+			DBG_RSV(1, "return %d\n", ret);
 		}
 	}
 	spin_unlock(&c->erase_completion_lock);
@@ -154,13 +153,13 @@
 	int ret = -EAGAIN;
 	minsize = PAD(minsize);
 
-	DBG_RSV(1, "jffs3_reserve_space_gc(): Requested 0x%x bytes\n", minsize);
+	DBG_RSV(1, "jffs3_reserve_space_gc(): Requested %#x bytes\n", minsize);
 
 	spin_lock(&c->erase_completion_lock);
 	while(ret == -EAGAIN) {
 		ret = jffs3_do_reserve_space(c, minsize, ofs, len, sumsize);
 		if (ret) {
-		        DBG_RSV(1, "looping, ret is %d\n", ret);
+		        DBG_RSV(1, "Looping, ret is %d\n", ret);
 		}
 	}
 	spin_unlock(&c->erase_completion_lock);
@@ -172,23 +171,23 @@
 {
 	struct jffs3_eraseblock *jeb = c->nextblock;
 	uint32_t nofree_size;
-	
+
  restart:
 	nofree_size = 0;
-	
+
 #ifdef CONFIG_JFFS3_SUMMARY
 
 	if (sumsize != JFFS3_SUMMARY_NOSUM_SIZE) {
 		int ret;
-		
+
 		if (jeb) {
 		    if ((ret=jffs3_sum_care_sum_collected(jeb))) return ret;
 		    nofree_size = sumsize + jeb->sum_collected->sum_size + JFFS3_SUMMARY_FRAME_SIZE;
 		}
-		
+
 		DBG_SUMMARY(1,"minsize %d , jeb->free(%d) , sum_collected->size(%d) , sumsize(%d)\n",
 		minsize,jeb->free_size,jeb->sum_collected->sum_size,sumsize);
-		
+
 		if (jeb && (minsize + jeb->sum_collected->sum_size + sumsize + JFFS3_SUMMARY_FRAME_SIZE > jeb->free_size)) {
 			DBG_SUMMARY(1,"generating summary for 0x%08x.\n", jeb->offset);
 			if (jeb->sum_collected->sum_size == JFFS3_SUMMARY_NOSUM_SIZE) {
@@ -196,19 +195,19 @@
 				jffs3_sum_clean_collected(jeb);
 				goto restart;
 			}
-			
+
 			ret = jffs3_sum_write_sumnode(c);
-			
+
 			if (ret)
 				return ret;
-			
+
 			if (jeb->sum_collected->sum_size == JFFS3_SUMMARY_NOSUM_SIZE) {
 				/* jffs3_write_sumnode can't write out the summary information */
 				sumsize = JFFS3_SUMMARY_NOSUM_SIZE;
 				jffs3_sum_clean_collected(jeb);
 				goto restart;
 			}
-			
+
 			/* Check, if we have a dirty block now, or if it was dirty already */
 			if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) {
 				c->dirty_size += jeb->wasted_size;
@@ -226,7 +225,7 @@
 						jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size);
 					list_add_tail(&jeb->list, &c->dirty_list);
 				}
-			} else { 
+			} else {
 				DBG_BL(1, "Adding full erase block at 0x%08x to clean_list "
 					"(free 0x%08x, dirty 0x%08x, used 0x%08x\n",
  					jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size);
@@ -234,7 +233,7 @@
 			}
 			c->nextblock = jeb = NULL;
 		}
-	} else {	
+	} else {
 #endif
 		if (jeb && minsize > jeb->free_size) {
 			/* Skip the end of this block and file it as having some dirty space */
@@ -251,7 +250,7 @@
 			c->free_size -= jeb->free_size;
 			jeb->wasted_size += jeb->free_size;
 			jeb->free_size = 0;
-			
+
 			/* Check, if we have a dirty block now, or if it was dirty already */
 			if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) {
 				c->dirty_size += jeb->wasted_size;
@@ -269,7 +268,7 @@
 						jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size);
 					list_add_tail(&jeb->list, &c->dirty_list);
 				}
-			} else { 
+			} else {
 				DBG_BL(1, "Adding full erase block at 0x%08x to clean_list (free 0x%08x, "
 					"dirty 0x%08x, used 0x%08x\n",
 					jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size);
@@ -279,14 +278,14 @@
 		}
 #ifdef CONFIG_JFFS3_SUMMARY
  	}
-#endif		
+#endif
 	if (!jeb) {
 		struct list_head *next;
 		/* Take the next block off the 'free' list */
 
 		if (list_empty(&c->free_list)) {
 
-			if (!c->nr_erasing_blocks && 
+			if (!c->nr_erasing_blocks &&
 			    !list_empty(&c->erasable_list)) {
 				struct jffs3_eraseblock *ejeb;
 
@@ -299,10 +298,10 @@
 					  ejeb->offset);
 			}
 
-			if (!c->nr_erasing_blocks && 
+			if (!c->nr_erasing_blocks &&
 			    !list_empty(&c->erasable_pending_wbuf_list)) {
 				DBG_RSV(1, "Flushing write buffer\n");
-				/* c->nextblock is NULL, no update to c->nextblock allowed */			    
+				/* c->nextblock is NULL, no update to c->nextblock allowed */
 				spin_unlock(&c->erase_completion_lock);
 				jffs3_flush_wbuf_pad(c);
 				spin_lock(&c->erase_completion_lock);
@@ -315,9 +314,9 @@
 				   And there's no space left. At all. */
 				WARNING_MSG("Argh. No free space left for GC. nr_erasing_blocks is %d."
 					" nr_free_blocks is %d. (erasableempty: %s, erasingempty: %s, "
-					"erasependingempty: %s)\n", 
+					"erasependingempty: %s)\n",
 				       c->nr_erasing_blocks, c->nr_free_blocks,
-				       list_empty(&c->erasable_list)?"yes" : "no", 
+				       list_empty(&c->erasable_list)?"yes" : "no",
 				       list_empty(&c->erasing_list)?"yes" : "no",
 				       list_empty(&c->erase_pending_list)?"yes":"no");
 				return -ENOSPC;
@@ -352,9 +351,9 @@
 
 	if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size &&
 	    !jeb->first_node->next_in_ino) {
-		/* Only node in it beforehand was a CLEANMARKER node (we think). 
+		/* Only node in it beforehand was a CLEANMARKER node (we think).
 		   So mark it obsolete now that there's going to be another node
-		   in the block. This will reduce used_size to zero but We've 
+		   in the block. This will reduce used_size to zero but We've
 		   already set c->nextblock so that jffs3_mark_node_obsolete()
 		   won't try to refile it to the dirty_list.
 		*/
@@ -363,7 +362,7 @@
 		spin_lock(&c->erase_completion_lock);
 	}
 
-	DBG_RSV(1, "Giving 0x%x bytes at 0x%x\n", *len, *ofs);
+	DBG_RSV(1, "Giving %#x bytes at %#x\n", *len, *ofs);
 	return 0;
 }
 
@@ -372,29 +371,27 @@
  *	@c: superblock info
  *	@new: new node reference to add
  *	@len: length of this physical node
- *	@dirty: dirty flag for new node
  *
- *	Should only be used to report nodes for which space has been allocated 
+ *	Should only be used to report nodes for which space has been allocated
  *	by jffs3_reserve_space.
  *
  *	Must be called with the alloc_sem held.
  */
-int jffs3_add_physical_node_ref(struct jffs3_sb_info *c, struct jffs3_raw_node_ref *new)
+int jffs3_add_physical_node_ref(struct jffs3_sb_info *c, struct jffs3_raw_node_ref *new, uint32_t len)
 {
 	struct jffs3_eraseblock *jeb;
-	uint32_t len;
 
 	jeb = &c->blocks[new->flash_offset / c->sector_size];
-	len = ref_totlen(c, jeb, new);
 
 	DBG_NR(1, "Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len);
-#if 1
-	if (jeb != c->nextblock || (ref_offset(new)) != jeb->offset + (c->sector_size - jeb->free_size)) {
-		WARNING_MSG("argh. node added in wrong place\n");
+	if (DEBUG2)
+		jffs3_dbg_dump_node_refs(c, jeb);
+
+	if (SANITY && jffs3_dbg_node_add_sanity_check(c, jeb, new, len)) {
 		jffs3_free_raw_node_ref(new);
 		return -EINVAL;
 	}
-#endif
+
 	spin_lock(&c->erase_completion_lock);
 
 	if (!jeb->first_node)
@@ -434,6 +431,9 @@
 
 	spin_unlock(&c->erase_completion_lock);
 
+	if (DEBUG2)
+		jffs3_dbg_dump_node_refs(c, jeb);
+
 	return 0;
 }
 
@@ -471,7 +471,7 @@
 		ERROR_MSG("called with NULL node\n");
 		BUG();
 	}
-	
+
 	if (ref_obsolete(ref)) {
 		DBG_NR(1, "called with already obsolete node at 0x%08x\n", ref_offset(ref));
 		return;
@@ -486,8 +486,8 @@
 
 	if (jffs3_can_mark_obsolete(c) && !jffs3_is_readonly(c) &&
 	    !(c->flags & JFFS3_SB_FLAG_MOUNTING)) {
-		/* Hm. This may confuse static lock analysis. If any of the above 
-		   three conditions is false, we're going to return from this 
+		/* Hm. This may confuse static lock analysis. If any of the above
+		   three conditions is false, we're going to return from this
 		   function without actually obliterating any nodes or freeing
 		   any jffs3_raw_node_refs. So we don't need to stop erases from
 		   happening, or protect against people holding an obsolete
@@ -515,7 +515,7 @@
 				ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size);
 			BUG();
 		}
-		DBG_NR(1, "Obsoleting node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(c, jeb, ref));
+		DBG_NR(1, "Obsoleting node at 0x%08x of len %x\n", ref_offset(ref), ref_totlen(c, jeb, ref));
 		jeb->used_size -= ref_totlen(c, jeb, ref);
 		c->used_size -= ref_totlen(c, jeb, ref);
 	}
@@ -547,10 +547,10 @@
 		DBG_NR(1, "Wasting\n");
 		addedsize = 0;
 		jeb->wasted_size += ref_totlen(c, jeb, ref);
-		c->wasted_size += ref_totlen(c, jeb, ref);	
+		c->wasted_size += ref_totlen(c, jeb, ref);
 	}
 	ref->flash_offset = ref_offset(ref) | REF_OBSOLETE;
-	
+
 	jffs3_dbg_acct_sanity_check(c, jeb);
 	if (PARANOIA)
 		jffs3_dbg_acct_paranoia_check(c, jeb);
@@ -558,7 +558,7 @@
 	if (c->flags & JFFS3_SB_FLAG_MOUNTING) {
 		/* Mount in progress. Don't muck about with the block
 		   lists because they're not ready yet, and don't actually
-		   obliterate nodes that look obsolete. If they weren't 
+		   obliterate nodes that look obsolete. If they weren't
 		   marked obsolete on the flash at the time they _became_
 		   obsolete, there was probably a reason for that. */
 		spin_unlock(&c->erase_completion_lock);
@@ -593,7 +593,7 @@
 				   immediately reused, and we spread the load a bit. */
 				DBG_BL(1, "...and adding to erasable_list\n");
 				list_add_tail(&jeb->list, &c->erasable_list);
-			}				
+			}
 		}
 		DBG_NR(1, "Done OK\n");
 	} else if (jeb == c->gcblock) {
@@ -611,8 +611,8 @@
 		list_add_tail(&jeb->list, &c->very_dirty_list);
 	} else {
 		DBG_NR(1, "Eraseblock at 0x%08x not moved anywhere. (free 0x%08x, dirty 0x%08x, used 0x%08x)\n",
-			jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size); 
-	}			  	
+			jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size);
+	}
 
 	spin_unlock(&c->erase_completion_lock);
 
@@ -660,11 +660,11 @@
 
 	/* Nodes which have been marked obsolete no longer need to be
 	   associated with any inode. Remove them from the per-inode list.
-	   
-	   Note we can't do this for NAND at the moment because we need 
+
+	   Note we can't do this for NAND at the moment because we need
 	   obsolete dirent nodes to stay on the lists, because of the
 	   horridness in jffs3_garbage_collect_deletion_dirent(). Also
-	   because we delete the inocache, and on NAND we need that to 
+	   because we delete the inocache, and on NAND we need that to
 	   stay around until all the nodes are actually erased, in order
 	   to stop us from giving the same inode number to another newly
 	   created inode. */
@@ -696,10 +696,12 @@
 	if (ref->next_phys && ref_obsolete(ref->next_phys) &&
 	    !ref->next_phys->next_in_ino) {
 		struct jffs3_raw_node_ref *n = ref->next_phys;
-		
+
 		spin_lock(&c->erase_completion_lock);
 
+#ifdef TMP_TOTLEN
 		ref->__totlen += n->__totlen;
+#endif
 		ref->next_phys = n->next_phys;
                 if (jeb->last_node == n) jeb->last_node = ref;
 		if (jeb->gc_node == n) {
@@ -710,7 +712,7 @@
 
 		jffs3_free_raw_node_ref(n);
 	}
-	
+
 	/* Also merge with the previous node in the list, if there is one
 	   and that one is obsolete */
 	if (ref != jeb->first_node ) {
@@ -720,9 +722,11 @@
 
 		while (p->next_phys != ref)
 			p = p->next_phys;
-		
+
 		if (ref_obsolete(p) && !ref->next_in_ino) {
+#ifdef TMP_TOTLEN
 			p->__totlen += ref->__totlen;
+#endif
 			if (jeb->last_node == ref) {
 				jeb->last_node = p;
 			}
@@ -760,11 +764,11 @@
 	 */
 	dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size;
 
-	if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger && 
-			(dirty > c->nospc_dirty_size)) 
+	if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger &&
+			(dirty > c->nospc_dirty_size))
 		ret = 1;
 
-	DBG_GCT(1, "nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x: %s\n", 
+	DBG_GCT(1, "nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x: %s\n",
 		  c->nr_free_blocks, c->nr_erasing_blocks, c->dirty_size, ret ? "yes" : "no");
 
 	return ret;

Index: os-linux.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/os-linux.h,v
retrieving revision 3.2
retrieving revision 3.3
diff -u -r3.2 -r3.3
--- os-linux.h	21 Dec 2004 15:18:51 -0000	3.2
+++ os-linux.h	25 Dec 2004 11:11:21 -0000	3.3
@@ -132,7 +132,7 @@
 #else
 #define jffs3_can_mark_obsolete(c) (0)
 #endif
-	
+
 #define jffs3_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH)
 
 #define jffs3_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf))
@@ -212,8 +212,8 @@
 struct jffs3_inode_info *jffs3_gc_fetch_inode(struct jffs3_sb_info *c,
 					      int inum, int nlink);
 
-unsigned char *jffs3_gc_fetch_page(struct jffs3_sb_info *c, 
-				   struct jffs3_inode_info *f, 
+unsigned char *jffs3_gc_fetch_page(struct jffs3_sb_info *c,
+				   struct jffs3_inode_info *f,
 				   unsigned long offset,
 				   unsigned long *priv);
 void jffs3_gc_release_page(struct jffs3_sb_info *c,
@@ -221,10 +221,10 @@
 			   unsigned long *priv);
 int jffs3_flash_setup(struct jffs3_sb_info *c);
 void jffs3_flash_cleanup(struct jffs3_sb_info *c);
-     
+
 
 /* writev.c */
-int jffs3_flash_direct_writev(struct jffs3_sb_info *c, const struct kvec *vecs, 
+int jffs3_flash_direct_writev(struct jffs3_sb_info *c, const struct kvec *vecs,
 		       unsigned long count, loff_t to, size_t *retlen);
 
 

Index: rbtree.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/rbtree.c,v
retrieving revision 3.1
retrieving revision 3.2
diff -u -r3.1 -r3.2
--- rbtree.c	9 Dec 2004 16:05:06 -0000	3.1
+++ rbtree.c	25 Dec 2004 11:11:21 -0000	3.2
@@ -2,7 +2,7 @@
   Red Black Trees
   (C) 1999  Andrea Arcangeli <andrea at suse.de>
   (C) 2002  David Woodhouse <dwmw2 at infradead.org>
-  
+
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
@@ -309,7 +309,7 @@
 	/* If we have a right-hand child, go down and then left as far
 	   as we can. */
 	if (node->rb_right) {
-		node = node->rb_right; 
+		node = node->rb_right;
 		while (node->rb_left)
 			node=node->rb_left;
 		return node;
@@ -330,7 +330,7 @@
 struct rb_node *rb_prev(struct rb_node *node)
 {
 	if (node->rb_left) {
-		node = node->rb_left; 
+		node = node->rb_left;
 		while (node->rb_right)
 			node=node->rb_right;
 		return node;

Index: read.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/read.c,v
retrieving revision 3.5
retrieving revision 3.6
diff -u -r3.5 -r3.6
--- read.c	23 Dec 2004 18:53:37 -0000	3.5
+++ read.c	25 Dec 2004 11:11:21 -0000	3.6
@@ -62,7 +62,7 @@
 	}
 	/* There was a bug where we wrote hole nodes out with csize/dsize
 	   swapped. Deal with it */
-	if (ri->compr == JFFS3_COMPR_ZERO && !je32_to_cpu(ri->dsize) && 
+	if (ri->compr == JFFS3_COMPR_ZERO && !je32_to_cpu(ri->dsize) &&
 	    je32_to_cpu(ri->csize)) {
 		ri->dsize = ri->csize;
 		ri->csize = cpu_to_je32(0);
@@ -75,7 +75,7 @@
 		goto out_ri;
 	};
 
-	
+
 	if (ri->compr == JFFS3_COMPR_ZERO) {
 		memset(buf, 0, len);
 		goto out_ri;
@@ -83,8 +83,8 @@
 
 	/* Cases:
 	   Reading whole node and it's uncompressed - read directly to buffer provided, check CRC.
-	   Reading whole node and it's compressed - read into comprbuf, check CRC and decompress to buffer provided 
-	   Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy 
+	   Reading whole node and it's compressed - read into comprbuf, check CRC and decompress to buffer provided
+	   Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy
 	   Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy
 	*/
 	if (ri->compr == JFFS3_COMPR_NONE && len == je32_to_cpu(ri->dsize)) {
@@ -129,7 +129,7 @@
 	DBG_READ(2, "Data CRC matches calculated CRC %08x\n", crc);
 	if (ri->compr != JFFS3_COMPR_NONE) {
 		DBG_READ(2, "Decompress %d bytes from %p to %d bytes at %p\n",
-				je32_to_cpu(ri->csize), readbuf, je32_to_cpu(ri->dsize), decomprbuf); 
+				je32_to_cpu(ri->csize), readbuf, je32_to_cpu(ri->dsize), decomprbuf);
 		ret = jffs3_decompress(c, f, ri->compr | (ri->usercompr << 8), readbuf, decomprbuf, je32_to_cpu(ri->csize), je32_to_cpu(ri->dsize));
 		if (ret) {
 			WARNING_MSG("jffs3_decompress returned %d\n", ret);
@@ -159,7 +159,7 @@
 	struct jffs3_node_frag *frag;
 	int ret;
 
-	DBG_READ(1, "ino #%u, range 0x%08x-0x%08x\n", f->inocache->ino, offset, offset+len);
+	DBG_READ(1, "Inode #%u, range 0x%08x-0x%08x\n", f->inocache->ino, offset, offset+len);
 
 	frag = jffs3_lookup_node_frag(&f->fragtree, offset);
 
@@ -176,17 +176,18 @@
 				holesize = min(holesize, frag->ofs - offset);
 				if (DEBUG2) {
 					DBG_READ(2, "The fragment tree dump:\n");
-					jffs3_dbg_print_frag_list(f);
+					jffs3_dbg_dump_frag_list(f);
 				}
 			}
-			DBG_READ(1, "Filling non-frag hole from %d-%d\n", offset, offset+holesize);
+			DBG_READ(1, "Filling non-frag hole %d-%d\n",
+					offset, offset + holesize);
 			memset(buf, 0, holesize);
 			buf += holesize;
 			offset += holesize;
 			continue;
 		} else if (unlikely(!frag->node)) {
 			uint32_t holeend = min(end, frag->ofs + frag->size);
-			DBG_READ(1, "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n",
+			DBG_READ(1, "Filling frag hole %d-%d (frag %#x %#x)\n",
 				offset, holeend, frag->ofs, frag->ofs + frag->size);
 			memset(buf, 0, holeend - offset);
 			buf += holeend - offset;
@@ -196,7 +197,7 @@
 		} else {
 			uint32_t readlen;
 			uint32_t fragofs; /* offset within the frag to start reading */
-			
+
 			fragofs = offset - frag->ofs;
 			readlen = min(frag->size - fragofs, end - offset);
 			DBG_READ(1, "Reading %d-%d from node at 0x%08x (%d)\n",

Index: readinode.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/readinode.c,v
retrieving revision 3.5
retrieving revision 3.6
diff -u -r3.5 -r3.6
--- readinode.c	23 Dec 2004 18:53:37 -0000	3.5
+++ readinode.c	25 Dec 2004 11:11:21 -0000	3.6
@@ -39,7 +39,7 @@
 				  this->node->frags);
 			mark_ref_normal(this->node->raw);
 		}
-		
+
 	}
 	jffs3_free_node_frag(this);
 }
@@ -60,7 +60,7 @@
 
 	DBG_BI(2, "adding node %04x-%04x @0x%08x on flash, newfrag *%p\n",
 		  fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag);
-	
+
 	if (unlikely(!fn->size)) {
 		jffs3_free_node_frag(newfrag);
 		return 0;
@@ -81,14 +81,14 @@
 		struct jffs3_node_frag *prev = frag_prev(newfrag);
 
 		mark_ref_normal(fn->raw);
-		/* If we don't start at zero there's _always_ a previous */	
+		/* If we don't start at zero there's _always_ a previous */
 		if (prev->node)
 			mark_ref_normal(prev->node->raw);
 	}
 
 	if ((newfrag->ofs+newfrag->size) & (PAGE_CACHE_SIZE-1)) {
 		struct jffs3_node_frag *next = frag_next(newfrag);
-		
+
 		if (next) {
 			mark_ref_normal(fn->raw);
 			if (next->node)
@@ -98,9 +98,9 @@
 
 	if (DEBUG2) {
 		DBG_BI(2, "The fragment tree dump:\n");
-		jffs3_dbg_print_frag_list(f);
+		jffs3_dbg_dump_frag_list(f);
 	}
-	
+
 	return 0;
 }
 
@@ -122,7 +122,7 @@
 		DBG_BI(2, "Lookup gave no frag\n");
 		lastend = 0;
 	}
-			  
+
 	/* See if we ran off the end of the list */
 	if (lastend <= newfrag->ofs) {
 		/* We did */
@@ -148,7 +148,7 @@
 			holefrag->size = newfrag->node->ofs - lastend;
 			holefrag->node = NULL;
 			if (this) {
-				/* By definition, the 'this' node has no right-hand child, 
+				/* By definition, the 'this' node has no right-hand child,
 				   because there are no frags with offset greater than it.
 				   So that's where we want to put the hole */
 				DBG_BI(2, "Adding hole frag (%p) on right of node at (%p)\n", holefrag, this);
@@ -161,11 +161,11 @@
 			this = holefrag;
 		}
 		if (this) {
-			/* By definition, the 'this' node has no right-hand child, 
+			/* By definition, the 'this' node has no right-hand child,
 			   because there are no frags with offset greater than it.
 			   So that's where we want to put the hole */
 			DBG_BI(2, "Adding new frag (%p) on right of node at (%p)\n", newfrag, this);
-			rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);			
+			rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);
 		} else {
 			DBG_BI(2, "Adding new frag (%p) at root of tree\n", newfrag);
 			rb_link_node(&newfrag->rb, NULL, &list->rb_node);
@@ -174,12 +174,12 @@
 		return 0;
 	}
 
-	DBG_BI(2, "dealing with frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n", 
+	DBG_BI(2, "dealing with frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n",
 		  this->ofs, this->ofs+this->size,
 		  this->node ? (ref_offset(this->node->raw)) : 0xffffffff, this);
 
 	/* OK. 'this' is pointing at the first frag that newfrag->ofs at least partially obsoletes,
-	 * - i.e. newfrag->ofs < this->ofs+this->size && newfrag->ofs >= this->ofs  
+	 * - i.e. newfrag->ofs < this->ofs+this->size && newfrag->ofs >= this->ofs
 	 */
 	if (newfrag->ofs > this->ofs) {
 		/* This node isn't completely obsoleted. The start of it remains valid */
@@ -197,15 +197,15 @@
 				jffs3_free_node_frag(newfrag);
 				return -ENOMEM;
 			}
-			
+
 			if (DEBUG2) {
 				DBG_BI(2, "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size);
 				if (this->node)
 					DBG_BI(2, "phys 0x%08x\n", ref_offset(this->node->raw));
-				else 
+				else
 					DBG_BI(2, "hole\n");
 			}
-			
+
 			/* New second frag pointing to this's node */
 			newfrag2->ofs = newfrag->ofs + newfrag->size;
 			newfrag2->size = (this->ofs+this->size) - newfrag2->ofs;
@@ -224,10 +224,10 @@
 			   from newfrag to insert newfrag2. */
 			jffs3_fragtree_insert(newfrag, this);
 			rb_insert_color(&newfrag->rb, list);
-			
+
 			jffs3_fragtree_insert(newfrag2, newfrag);
 			rb_insert_color(&newfrag2->rb, list);
-			
+
 			return 0;
 		}
 		/* New node just reduces 'this' frag in size, doesn't split it */
@@ -237,14 +237,14 @@
 		jffs3_fragtree_insert(newfrag, this);
 		rb_insert_color(&newfrag->rb, list);
 	} else {
-		/* New frag starts at the same point as 'this' used to. Replace 
+		/* New frag starts at the same point as 'this' used to. Replace
 		   it in the tree without doing a delete and insertion */
 		DBG_BI(2, "Inserting newfrag (*%p),%d-%d in before 'this' (*%p),%d-%d\n",
 			  newfrag, newfrag->ofs, newfrag->ofs+newfrag->size,
 			  this, this->ofs, this->ofs+this->size);
-	
+
 		rb_replace_node(&this->rb, &newfrag->rb, list);
-		
+
 		if (newfrag->ofs + newfrag->size >= this->ofs+this->size) {
 			DBG_BI(2, "Obsoleting node frag %p (%x-%x)\n", this, this->ofs, this->ofs+this->size);
 			jffs3_obsolete_node_frag(c, this);
@@ -258,7 +258,7 @@
 		}
 	}
 	/* OK, now we have newfrag added in the correct place in the tree, but
-	   frag_next(newfrag) may be a fragment which is overlapped by it 
+	   frag_next(newfrag) may be a fragment which is overlapped by it
 	*/
 	while ((this = frag_next(newfrag)) && newfrag->ofs + newfrag->size >= this->ofs + this->size) {
 		/* 'this' frag is obsoleted completely. */
@@ -267,7 +267,7 @@
 		rb_erase(&this->rb, list);
 		jffs3_obsolete_node_frag(c, this);
 	}
-	/* Now we're pointing at the first frag which isn't totally obsoleted by 
+	/* Now we're pointing at the first frag which isn't totally obsoleted by
 	   the new frag */
 
 	if (!this || newfrag->ofs + newfrag->size == this->ofs) {
@@ -311,14 +311,14 @@
 
 /* Scan the list of all nodes present for this ino, build map of versions, etc. */
 
-static int jffs3_do_read_inode_internal(struct jffs3_sb_info *c, 
+static int jffs3_do_read_inode_internal(struct jffs3_sb_info *c,
 					struct jffs3_inode_info *f,
 					struct jffs3_raw_inode *latest_node);
 
-int jffs3_do_read_inode(struct jffs3_sb_info *c, struct jffs3_inode_info *f, 
+int jffs3_do_read_inode(struct jffs3_sb_info *c, struct jffs3_inode_info *f,
 			uint32_t ino, struct jffs3_raw_inode *latest_node)
 {
-	DBG_RI(2, "entering\n");
+	DBG_RI(2, "Read ino #%u\n", ino);
 
  retry_inocache:
 	spin_lock(&c->inocache_lock);
@@ -333,7 +333,7 @@
 		case INO_STATE_CHECKEDABSENT:
 			f->inocache->state = INO_STATE_READING;
 			break;
-			
+
 		case INO_STATE_CHECKING:
 		case INO_STATE_GC:
 			/* If it's in either of these states, we need
@@ -365,7 +365,7 @@
 		/* Special case - no root inode on medium */
 		f->inocache = jffs3_alloc_inode_cache();
 		if (!f->inocache) {
-			WARNING_MSG("jffs3_do_read_inode(): Cannot allocate inocache for root inode\n");
+			WARNING_MSG("Cannot allocate inocache for root inode\n");
 			return -ENOMEM;
 		}
 		DBG_RI(1, "Creating inocache for root inode\n");
@@ -405,7 +405,7 @@
 	return ret;
 }
 
-static int jffs3_do_read_inode_internal(struct jffs3_sb_info *c, 
+static int jffs3_do_read_inode_internal(struct jffs3_sb_info *c,
 					struct jffs3_inode_info *f,
 					struct jffs3_raw_inode *latest_node)
 {
@@ -418,7 +418,9 @@
 	size_t retlen;
 	int ret;
 
-	DBG_RI(1, "ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink);
+	DBG_RI(1, "read ino #%u, nlink %d, state %d\n",
+		f->inocache->ino, f->inocache->nlink,
+		f->inocache->state);
 
 	/* Grab all nodes relevant to this ino */
 	ret = jffs3_get_inode_nodes(c, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);
@@ -442,7 +444,7 @@
 				jffs3_mark_node_obsolete(c, f->metadata->raw);
 				jffs3_free_full_dnode(f->metadata);
 				f->metadata = NULL;
-				
+
 				mdata_ver = 0;
 			} else {
 				/* This should never happen. */
@@ -524,7 +526,7 @@
 		}
 		break;
 
-			
+
 	case S_IFREG:
 		/* If it was a regular file, truncate it to the latest node's isize */
 		jffs3_truncate_fraglist(c, &f->fragtree, je32_to_cpu(latest_node->isize));

Index: scan.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/scan.c,v
retrieving revision 3.6
retrieving revision 3.7
diff -u -r3.6 -r3.7
--- scan.c	22 Dec 2004 18:35:51 -0000	3.6
+++ scan.c	25 Dec 2004 11:11:22 -0000	3.7
@@ -20,32 +20,22 @@
 #include <linux/compiler.h>
 #include "nodelist.h"
 #include "summary.h"
-
-#define EMPTY_SCAN_SIZE 1024
-
-#define DBG_NOISY(noise, args...) do { \
-	if (*(noise)) { \
-		NOTICE_MSG(args); \
-		(*(noise))--; \
-		if (!(*(noise))) \
-			NOTICE_MSG("Further such events for this erase block will not be printed\n"); \
-	} \
-} while(0)
+#include "scan.h"
 
 static uint32_t pseudo_random;
 
 static int jffs3_scan_eraseblock (struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb,
 				  unsigned char *buf, uint32_t buf_size);
 
-/* These helper functions _must_ increase ofs and also do the dirty/used space accounting. 
+/* These helper functions _must_ increase ofs and also do the dirty/used space accounting.
  * Returning an error will abort the mount - bad checksums etc. should just mark the space
  * as dirty.
  */
-static int jffs3_scan_inode_node(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb, 
+static int jffs3_scan_inode_node(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb,
 				 struct jffs3_raw_inode *ri, uint32_t ofs);
 static int jffs3_scan_dirent_node(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb,
 				 struct jffs3_raw_dirent *rd, uint32_t ofs);
-					 
+
 static inline int min_free(struct jffs3_sb_info *c)
 {
 	uint32_t min = 2 * sizeof(struct jffs3_raw_inode);
@@ -109,8 +99,8 @@
 		/* Now decide which list to put it on */
 		switch(ret) {
 		case BLK_STATE_ALLFF:
-			/* 
-			 * Empty block.   Since we can't be sure it 
+			/*
+			 * Empty block.   Since we can't be sure it
 			 * was entirely erased, we just queue it for erase
 			 * again.  It will be marked as such when the erase
 			 * is complete.  Meanwhile we still count it as empty
@@ -145,7 +135,7 @@
                         /* Some data, but not full. Dirty list. */
                         /* We want to remember the block with most free space
                            and stick it in the 'nextblock' position to start writing to it. */
-                        if (jeb->free_size > min_free(c) && 
+                        if (jeb->free_size > min_free(c) &&
 			    (!c->nextblock || c->nextblock->free_size < jeb->free_size)) {
                                 /* Better candidate for the next writes to go to */
                                 if (c->nextblock) {
@@ -183,7 +173,7 @@
 			list_add(&jeb->list, &c->erase_pending_list);
 			c->nr_erasing_blocks++;
 			break;
-			
+
 		case BLK_STATE_BADBLOCK:
 			DBG_SCAN(1, "Block at %#08x is bad\n", jeb->offset);
 			list_add(&jeb->list, &c->bad_list);
@@ -193,10 +183,10 @@
 			break;
 		default:
 			ERROR_MSG("Unknown block state\n");
-			BUG();	
+			BUG();
 		}
 	}
-	
+
 	/* Nextblock dirty is always seen as wasted, because we cannot recycle it now */
 	if (c->nextblock && (c->nextblock->dirty_size)) {
 		c->nextblock->wasted_size += c->nextblock->dirty_size;
@@ -206,7 +196,7 @@
 	}
 #if defined CONFIG_JFFS3_FS_NAND || defined CONFIG_JFFS3_FS_NOR_ECC
 	if (!jffs3_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) {
-		/* If we're going to start writing into a block which already 
+		/* If we're going to start writing into a block which already
 		   contains data, and the end of the data isn't page-aligned,
 		   skip a little and align it. */
 
@@ -222,7 +212,7 @@
 #endif
 	if (c->nr_erasing_blocks) {
 		if ( !c->used_size && ((c->nr_free_blocks + empty_blocks+bad_blocks)
-					!= c->nr_blocks || bad_blocks == c->nr_blocks) ) { 
+					!= c->nr_blocks || bad_blocks == c->nr_blocks) ) {
 			NOTICE_MSG("Cowardly refusing to erase blocks on filesystem with "
 					"no valid JFFS3 nodes\n");
 			NOTICE_MSG("Empty blocks %d, bad blocks %d, total blocks %d\n",
@@ -237,7 +227,7 @@
 	if (buf_size)
 		kfree(flashbuf);
 #ifndef __ECOS
-	else 
+	else
 		c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
 #endif
 	return ret;
@@ -275,11 +265,11 @@
 	uint32_t hdr_crc, buf_ofs, buf_len;
 	int err;
 	int noise = 0;
-	
+
 #ifdef CONFIG_JFFS3_SUMMARY
 	struct jffs3_sum_marker *sm;
-#endif	
-	
+#endif
+
 #ifdef CONFIG_JFFS3_FS_NAND
 	int cleanmarkerfound = 0;
 #endif
@@ -305,62 +295,61 @@
 		}
 	}
 #endif
-	
-#ifdef CONFIG_JFFS3_SUMMARY	
+
+#ifdef CONFIG_JFFS3_SUMMARY
 	sm = (struct jffs3_sum_marker *)kmalloc(sizeof(struct jffs3_sum_marker), GFP_KERNEL);
 	if (!sm) {
 	    return -ENOMEM;
 	}
-	
+
 	err = jffs3_fill_scan_buf(c, (unsigned char *) sm, jeb->offset + c->sector_size - sizeof(struct jffs3_sum_marker), sizeof(struct jffs3_sum_marker));
-	
+
 	if (err) {
 		kfree(sm);
 	        return err;
 	}
-	
+
 	if (je32_to_cpu(sm->magic) == JFFS3_SUM_MAGIC ) {
 
 		if(je32_to_cpu(sm->erase_size) == c->sector_size) {
 			int ret = jffs3_sum_scan_sumnode(c,jeb,je32_to_cpu(sm->offset),&pseudo_random);
-			
+
 			if (ret) {
 				kfree(sm);
 				return ret;
 			}
 		}
-		
+
 		WARNING_MSG("FS erase_block_size != JFFS3 erase_block_size => skipping summary information\n");
-		
+
 	}
-	
+
 	kfree(sm);
-	
+
 	ofs = jeb->offset;
 	prevofs = jeb->offset - 1;
-	
+
 #endif
-	
-	
+
 	buf_ofs = jeb->offset;
 
 	if (!buf_size) {
 		buf_len = c->sector_size;
-		
+
 #ifdef CONFIG_JFFS3_SUMMARY
 		/* must reread because of summary test */
 		err = jffs3_fill_scan_buf(c, buf, buf_ofs, buf_len);
 		if (err)
 			return err;
 #endif
-		
+
 	} else {
 		buf_len = EMPTY_SCAN_SIZE;
 		err = jffs3_fill_scan_buf(c, buf, buf_ofs, buf_len);
 		if (err)
 			return err;
 	}
-	
+
 	/* We temporarily use 'ofs' as a pointer into the buffer/jeb */
 	ofs = 0;
 
@@ -387,7 +376,8 @@
 	if (ofs) {
 		DBG_SCAN(2, "Free space at %#08x ends at %#08x\n",
 				jeb->offset, jeb->offset + ofs);
-		DIRTY_SPACE(ofs);
+		if (dirty_space(c, jeb, ofs) != 0)
+			return -ENOMEM;
 	}
 
 	/* Now ofs is a complete physical flash offset as it always was... */
@@ -395,11 +385,11 @@
 
 	noise = 10;
 
-#ifdef CONFIG_JFFS3_SUMMARY	
-	DBG_SUMMARY(1,"JFFS3: no summary found in jeb 0x%08x. Apply original scan.\n",jeb->offset);
+#ifdef CONFIG_JFFS3_SUMMARY
+	DBG_SUMMARY(1,"no summary found in jeb 0x%08x. Apply original scan.\n", jeb->offset);
 #endif
 
-scan_more:	
+scan_more:
 	while(ofs < jeb->offset + c->sector_size) {
 
 		if (PARANOIA)
@@ -407,17 +397,20 @@
 
 		cond_resched();
 
-		if (ofs & 3) {
+		if (SANITY && ofs & 3) {
 			WARNING_MSG("Eep. ofs %#08x not word-aligned!\n", ofs);
 			ofs = PAD(ofs);
 			continue;
 		}
-		if (ofs == prevofs) {
+
+		if (SANITY && ofs == prevofs) {
 			WARNING_MSG("ofs %#08x has already been seen. Skipping\n", ofs);
-			DIRTY_SPACE(4);
+			if (dirty_space(c, jeb, 4) != 0)
+				return -ENOMEM;
 			ofs += 4;
 			continue;
 		}
+
 		prevofs = ofs;
 
 		if (jeb->offset + c->sector_size < ofs + sizeof(*node)) {
@@ -425,7 +418,8 @@
 					"(%#08x+%#08x<%#08x+%zx Not reading\n",
 					sizeof(struct jffs3_unknown_node),
 					jeb->offset, c->sector_size, ofs, sizeof(*node));
-			DIRTY_SPACE((jeb->offset + c->sector_size)-ofs);
+			if (dirty_space(c, jeb, (jeb->offset + c->sector_size) - ofs) != 0)
+				return -ENOMEM;
 			break;
 		}
 
@@ -456,7 +450,8 @@
 				if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff) {
 					WARNING_MSG("Empty flash at %#08x ends at %#08x\n",
 						       empty_start, ofs);
-					DIRTY_SPACE(ofs-empty_start);
+					if (dirty_space(c, jeb, ofs - empty_start) != 0)
+						return -ENOMEM;
 					goto scan_more;
 				}
 
@@ -468,7 +463,7 @@
 
 			/* 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) && 
+			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);
@@ -478,7 +473,7 @@
 			/* 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 
+				/* No more to read. Break out of main loop without marking
 				   this range of empty space as dirty (because it's not) */
 				DBG_SCAN(1, "Empty flash at %#08x runs to end of "
 						"block. Treating as free_space\n", empty_start);
@@ -495,29 +490,27 @@
 		if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) {
 			WARNING_MSG("Magic bitmask is backwards at offset %#08x. "
 					"Wrong endian filesystem?\n", ofs);
-			DIRTY_SPACE(4);
+			if (dirty_space(c, jeb, 4) != 0)
+				return -ENOMEM;
 			ofs += 4;
 			continue;
 		}
+
 		if (je16_to_cpu(node->magic) == JFFS3_DIRTY_BITMASK) {
 			DBG_SCAN(1, "Dirty bitmask at %#08x\n", ofs);
-			DIRTY_SPACE(4);
-			ofs += 4;
-			continue;
-		}
-		if (je16_to_cpu(node->magic) == JFFS3_OLD_MAGIC_BITMASK) {
-			WARNING_MSG("Old JFFS3 bitmask found at %#08x\n", ofs);
-			WARNING_MSG("You cannot use older JFFS3 filesystems with newer kernels\n");
-			DIRTY_SPACE(4);
+			if (dirty_space(c, jeb, 4) != 0)
+				return -ENOMEM;
 			ofs += 4;
 			continue;
 		}
+
 		if (je16_to_cpu(node->magic) != JFFS3_MAGIC_BITMASK) {
 			/* OK. We're out of possibilities. Whinge and move on */
-			DBG_NOISY(&noise, "Magic bitmask 0x%04x not found at %#08x: 0x%04x instead\n", 
-				     JFFS3_MAGIC_BITMASK, ofs, 
+			DBG_NOISY(&noise, "Magic bitmask 0x%04x not found at %#08x: 0x%04x instead\n",
+				     JFFS3_MAGIC_BITMASK, ofs,
 				     je16_to_cpu(node->magic));
-			DIRTY_SPACE(4);
+			if (dirty_space(c, jeb, 4) != 0)
+				return -ENOMEM;
 			ofs += 4;
 			continue;
 		}
@@ -530,20 +523,22 @@
 		if (hdr_crc != je32_to_cpu(node->hdr_crc)) {
 			DBG_NOISY(&noise, "Node at %#08x {0x%04x, 0x%04x, %#08x) has "
 					"invalid CRC %#08x (calculated %#08x)\n",
-					ofs, je16_to_cpu(node->magic), je16_to_cpu(node->nodetype), 
+					ofs, je16_to_cpu(node->magic), je16_to_cpu(node->nodetype),
 					je32_to_cpu(node->totlen), je32_to_cpu(node->hdr_crc), hdr_crc);
-			DIRTY_SPACE(4);
+			if (dirty_space(c, jeb, 4) != 0)
+				return -ENOMEM;
 			ofs += 4;
 			continue;
 		}
 
-		if (ofs + je32_to_cpu(node->totlen) > 
+		if (ofs + je32_to_cpu(node->totlen) >
 		    jeb->offset + c->sector_size) {
 			/* Eep. Node goes over the end of the erase block. */
 			WARNING_MSG("Node at %#08x with length %#08x would run over the "
 					"end of the erase block\n", ofs, je32_to_cpu(node->totlen));
 			WARNING_MSG("Perhaps the file system was created ""with the wrong erase size?\n");
-			DIRTY_SPACE(4);
+			if (dirty_space(c, jeb, 4) != 0)
+				return -ENOMEM;
 			ofs += 4;
 			continue;
 		}
@@ -551,7 +546,8 @@
 		if (!(je16_to_cpu(node->nodetype) & JFFS3_NODE_ACCURATE)) {
 			/* Wheee. This is an obsoleted node */
 			DBG_SCAN(2, "Node at %#08x is obsolete. Skipping\n", ofs);
-			DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
+			if (dirty_space(c, jeb, je32_to_cpu(node->totlen)) != 0)
+				return -ENOMEM;
 			ofs += PAD(je32_to_cpu(node->totlen));
 			continue;
 		}
@@ -573,7 +569,7 @@
 			if (err) return err;
 			ofs += PAD(je32_to_cpu(node->totlen));
 			break;
-			
+
 		case JFFS3_NODETYPE_DIRENT:
 			if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) {
 				buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
@@ -595,36 +591,27 @@
 			DBG_SCAN(1, "CLEANMARKER node found at %#08x\n", ofs);
 			if (je32_to_cpu(node->totlen) != c->cleanmarker_size) {
 				NOTICE_MSG("CLEANMARKER node found at %#08x has totlen %#08x != normal %#08x\n",
-				       ofs, je32_to_cpu(node->totlen), c->cleanmarker_size);
-				DIRTY_SPACE(PAD(sizeof(struct jffs3_unknown_node)));
-				ofs += PAD(sizeof(struct jffs3_unknown_node));
-			} else if (jeb->first_node) {
-				WARNING_MSG("CLEANMARKER node found at %#08x, not first node in "
-					"block (%#08x)\n", ofs, jeb->offset);
-				DIRTY_SPACE(PAD(sizeof(struct jffs3_unknown_node)));
+					ofs, je32_to_cpu(node->totlen), c->cleanmarker_size);
+				if (dirty_space(c, jeb, sizeof(struct jffs3_unknown_node)) != 0)
+					return -ENOMEM;
 				ofs += PAD(sizeof(struct jffs3_unknown_node));
 			} else {
-				struct jffs3_raw_node_ref *marker_ref = jffs3_alloc_raw_node_ref();
-				if (!marker_ref) {
-					ERROR_MSG("Failed to allocate node ref for clean marker\n");
-					return -ENOMEM;
-				}
-				marker_ref->next_in_ino = NULL;
-				marker_ref->next_phys = NULL;
-				marker_ref->flash_offset = ofs | REF_NORMAL;
-				marker_ref->__totlen = c->cleanmarker_size;
-				jeb->first_node = jeb->last_node = marker_ref;
-			     
-				USED_SPACE(PAD(c->cleanmarker_size));
+				if (jeb->first_node)
+					WARNING_MSG("CLEANMARKER node found at %#08x, not first node in "
+						"block (%#08x)\n", ofs, jeb->offset);
+				if (dirty_space(c, jeb, c->cleanmarker_size) != 0)
+					return - ENOMEM;
 				ofs += PAD(c->cleanmarker_size);
 			}
 			break;
 
 		case JFFS3_NODETYPE_PADDING:
 #ifdef CONFIG_JFFS3_SUMMARY
-            jffs3_sum_add_padding_mem(jeb,je32_to_cpu(node->totlen));
+			jffs3_sum_add_padding_mem(jeb,je32_to_cpu(node->totlen));
 #endif
-			DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
+			DBG_SCAN(2, "Padding node found at %#08x (length %x)\n", ofs, je32_to_cpu(node->totlen));
+			if (dirty_space(c, jeb, je32_to_cpu(node->totlen)) != 0)
+				return - ENOMEM;
 			ofs += PAD(je32_to_cpu(node->totlen));
 			break;
 
@@ -636,7 +623,8 @@
 			        c->flags |= JFFS3_SB_FLAG_RO;
 				if (!(jffs3_is_readonly(c)))
 					return -EROFS;
-				DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
+				if (dirty_space(c, jeb, je32_to_cpu(node->totlen)) != 0)
+					return - ENOMEM;
 				ofs += PAD(je32_to_cpu(node->totlen));
 				break;
 
@@ -648,7 +636,8 @@
 			case JFFS3_FEATURE_RWCOMPAT_DELETE:
 				DBG_SCAN(1, "Unknown but compatible feature node (0x%04x) found at "
 						"offset %#08x\n", je16_to_cpu(node->nodetype), ofs);
-				DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
+				if (dirty_space(c, jeb, je32_to_cpu(node->totlen)) != 0)
+					return - ENOMEM;
 				ofs += PAD(je32_to_cpu(node->totlen));
 				break;
 
@@ -674,14 +663,14 @@
 		jeb->wasted_size = 0;
 	}
 
-	if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size 
+	if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size
 		&& (!jeb->first_node || !jeb->first_node->next_in_ino) )
 		return BLK_STATE_CLEANMARKER;
-		
-	/* move blocks with max 4 byte dirty space to cleanlist */	
+
+	/* move blocks with max 4 byte dirty space to cleanlist */
 	else if (!ISDIRTY(c->sector_size - (jeb->used_size + jeb->unchecked_size))) {
 		c->dirty_size -= jeb->dirty_size;
-		c->wasted_size += jeb->dirty_size; 
+		c->wasted_size += jeb->dirty_size;
 		jeb->wasted_size += jeb->dirty_size;
 		jeb->dirty_size = 0;
 		return BLK_STATE_CLEAN;
@@ -717,7 +706,7 @@
 	return ic;
 }
 
-static int jffs3_scan_inode_node(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb, 
+static int jffs3_scan_inode_node(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb,
 				 struct jffs3_raw_inode *ri, uint32_t ofs)
 {
 	struct jffs3_raw_node_ref *raw;
@@ -727,11 +716,11 @@
 	DBG_SCAN(1, "Node at %#08x\n", ofs);
 
 	/* We do very little here now. Just check the ino# to which we should attribute
-	   this node; we can do all the CRC checking etc. later. There's a tradeoff here -- 
+	   this node; we can do all the CRC checking etc. later. There's a tradeoff here --
 	   we used to scan the flash once only, reading everything we want from it into
 	   memory, then building all our in-core data structures and freeing the extra
 	   information. Now we allow the first part of the mount to complete a lot quicker,
-	   but we have to go _back_ to the flash in order to finish the CRC checking, etc. 
+	   but we have to go _back_ to the flash in order to finish the CRC checking, etc.
 	   Which means that the _full_ amount of time to get to proper write mode with GC
 	   operational may actually be _longer_ than before. Sucks to be me. */
 
@@ -751,9 +740,10 @@
 		if (crc != je32_to_cpu(ri->node_crc)) {
 			NOTICE_MSG("CRC failed on node at %#08x: Read %#08x, calculated %#08x\n",
 					ofs, je32_to_cpu(ri->node_crc), crc);
-			/* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */
-			DIRTY_SPACE(PAD(je32_to_cpu(ri->totlen)));
 			jffs3_free_raw_node_ref(raw);
+			/* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */
+			if (dirty_space(c, jeb, je32_to_cpu(ri->totlen)) != 0)
+				return -ENOMEM;
 			return 0;
 		}
 		ic = jffs3_scan_make_ino_cache(c, ino);
@@ -766,7 +756,9 @@
 	/* Wheee. It worked */
 
 	raw->flash_offset = ofs | REF_UNCHECKED;
+#ifdef TMP_TOTLEN
 	raw->__totlen = PAD(je32_to_cpu(ri->totlen));
+#endif
 	raw->next_phys = NULL;
 	raw->next_in_ino = ic->nodes;
 
@@ -784,15 +776,15 @@
 	pseudo_random += je32_to_cpu(ri->version);
 
 	UNCHECKED_SPACE(PAD(je32_to_cpu(ri->totlen)));
-	
+
 #ifdef CONFIG_JFFS3_SUMMARY
 	jffs3_sum_add_inode_mem(jeb,ri,ofs);
 #endif
-	
+
 	return 0;
 }
 
-static int jffs3_scan_dirent_node(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb, 
+static int jffs3_scan_dirent_node(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb,
 				  struct jffs3_raw_dirent *rd, uint32_t ofs)
 {
 	struct jffs3_raw_node_ref *raw;
@@ -810,7 +802,8 @@
 		NOTICE_MSG("Node CRC failed on node at %#08x: Read %#08x, calculated %#08x\n",
 			       ofs, je32_to_cpu(rd->node_crc), crc);
 		/* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */
-		DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen)));
+		if (dirty_space(c, jeb, je32_to_cpu(rd->totlen)) != 0)
+			return -ENOMEM;
 		return 0;
 	}
 
@@ -826,13 +819,14 @@
 	crc = crc32(0, fd->name, rd->nsize);
 	if (crc != je32_to_cpu(rd->name_crc)) {
 		NOTICE_MSG("jffs3_scan_dirent_node(): Name CRC failed on node at %#08x: Read %#08x, "
-				"calculated %#08x\n", ofs, je32_to_cpu(rd->name_crc), crc);	
+				"calculated %#08x\n", ofs, je32_to_cpu(rd->name_crc), crc);
 		DBG_SCAN(1, "Name for which CRC failed is (now) '%s', ino #%d\n",
 					fd->name, je32_to_cpu(rd->ino));
 		jffs3_free_full_dirent(fd);
 		/* FIXME: Why do we believe totlen? */
 		/* We believe totlen because the CRC on the node _header_ was OK, just the name failed. */
-		DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen)));
+		if (dirty_space(c, jeb, je32_to_cpu(rd->totlen)) != 0)
+			return -ENOMEM;
 		return 0;
 	}
 	raw = jffs3_alloc_raw_node_ref();
@@ -847,8 +841,10 @@
 		jffs3_free_raw_node_ref(raw);
 		return -ENOMEM;
 	}
-	
+
+#ifdef TMP_TOTLEN
 	raw->__totlen = PAD(je32_to_cpu(rd->totlen));
+#endif
 	raw->flash_offset = ofs | REF_PRISTINE;
 	raw->next_phys = NULL;
 	raw->next_in_ino = ic->nodes;

Index: summary.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/summary.c,v
retrieving revision 3.2
retrieving revision 3.3
diff -u -r3.2 -r3.3
--- summary.c	21 Dec 2004 16:07:52 -0000	3.2
+++ summary.c	25 Dec 2004 11:11:22 -0000	3.3
@@ -22,7 +22,7 @@
 #include <linux/vmalloc.h>
 #include "nodelist.h"
 
-int jffs3_sum_init(struct jffs3_sb_info *c) 
+int jffs3_sum_init(struct jffs3_sb_info *c)
 {
         c->summary_buf = (jint32_t *) vmalloc(c->sector_size);
         if (!c->summary_buf) {
@@ -32,7 +32,7 @@
         return 0;
 }
 
-void jffs3_sum_exit(struct jffs3_sb_info *c) 
+void jffs3_sum_exit(struct jffs3_sb_info *c)
 {
         if (c->summary_buf) {
                 vfree(c->summary_buf);
@@ -44,32 +44,32 @@
 {
 	if (!jeb->sum_collected) {
 		jeb->sum_collected = (struct jffs3_sum_info *) kmalloc(sizeof(struct jffs3_sum_info), GFP_KERNEL);
-	
+
 		if (!jeb->sum_collected)
 			return -ENOMEM;
-			
+
 		jeb->sum_collected->sum_list = NULL;
 		jeb->sum_collected->sum_num = 0;
-		jeb->sum_collected->sum_size = 0; 
-		jeb->sum_collected->sum_padded = 0; 
+		jeb->sum_collected->sum_size = 0;
+		jeb->sum_collected->sum_padded = 0;
 	}
         return 0;
 }
 
-static int jffs3_sum_add_mem(struct jffs3_eraseblock *jeb, union jffs3_sum_mem *item) 
+static int jffs3_sum_add_mem(struct jffs3_eraseblock *jeb, union jffs3_sum_mem *item)
 {
-	
+
 	union jffs3_sum_mem *walk;
         int ret;
-	
+
         if ((ret=jffs3_sum_care_sum_collected(jeb))) return ret;
-	
+
 	if (!jeb->sum_collected->sum_list) {
 		jeb->sum_collected->sum_list = (union jffs3_sum_mem *) item;
-	} 
+	}
 	else {
 		walk = jeb->sum_collected->sum_list;
-		
+
 		while (walk->u.next) {
 			walk = walk->u.next;
 		}
@@ -94,56 +94,56 @@
 void jffs3_sum_clean_all_info(struct jffs3_sb_info *c)
 {
 	int i;
-	
+
 	for (i=0; i<c->nr_blocks; i++) {
 		struct jffs3_eraseblock *jeb = &c->blocks[i];
-		
+
 		jffs3_sum_clean_collected(jeb);
 		kfree(jeb->sum_collected);
 		jeb->sum_collected = NULL;
 	}
 }
-	
+
 /* These 3 functions are called from scan.c to collect summary info for not closed jeb */
 
 int jffs3_sum_add_padding_mem(struct jffs3_eraseblock *jeb, uint32_t size)
 {
         int ret;
-	
+
         if ((ret=jffs3_sum_care_sum_collected(jeb))) return ret;
         jeb->sum_collected->sum_padded += size;
         return 0;
 }
 
-int jffs3_sum_add_inode_mem(struct jffs3_eraseblock *jeb, struct jffs3_raw_inode *ri, uint32_t ofs) 
+int jffs3_sum_add_inode_mem(struct jffs3_eraseblock *jeb, struct jffs3_raw_inode *ri, uint32_t ofs)
 {
-	
+
 	struct jffs3_sum_inode_mem *temp = (struct jffs3_sum_inode_mem *) kmalloc(sizeof(struct jffs3_sum_inode_mem), GFP_KERNEL);
-	
+
 	if (!temp)
 		return -ENOMEM;
 
         ofs -= jeb->offset;
-	
+
 	temp->nodetype = ri->nodetype;
 	temp->inode = ri->ino;
 	temp->version = ri->version;
-	temp->offset = cpu_to_je32(ofs); 
+	temp->offset = cpu_to_je32(ofs);
 	temp->totlen = ri->totlen;
 	temp->next = NULL;
-	
+
 	return jffs3_sum_add_mem(jeb, (union jffs3_sum_mem *)temp);
 }
 
-int jffs3_sum_add_dirent_mem(struct jffs3_eraseblock *jeb, struct jffs3_raw_dirent *rd, uint32_t ofs) 
+int jffs3_sum_add_dirent_mem(struct jffs3_eraseblock *jeb, struct jffs3_raw_dirent *rd, uint32_t ofs)
 {
-	
-	struct jffs3_sum_dirent_mem *temp = (struct jffs3_sum_dirent_mem *) 
+
+	struct jffs3_sum_dirent_mem *temp = (struct jffs3_sum_dirent_mem *)
 			kmalloc(sizeof(struct jffs3_sum_dirent_mem) + rd->nsize, GFP_KERNEL);
-	
+
 	if (!temp)
 		return -ENOMEM;
-	
+
         ofs -= jeb->offset;
 
 	temp->nodetype = rd->nodetype;
@@ -155,7 +155,7 @@
 	temp->nsize = rd->nsize;
 	temp->type = rd->type;
 	temp->next = NULL;
-	
+
 	memcpy(temp->name, rd->name, rd->nsize);
 
 	return jffs3_sum_add_mem(jeb, (union jffs3_sum_mem *)temp);
@@ -163,25 +163,25 @@
 
 /* Cleanup every collected summary information */
 
-void jffs3_sum_clean_collected(struct jffs3_eraseblock *jeb) 
+void jffs3_sum_clean_collected(struct jffs3_eraseblock *jeb)
 {
-	
+
 	union jffs3_sum_mem *temp;
-	
+
 	if(jeb && jeb->sum_collected){
-		
+
 		while(jeb->sum_collected->sum_list){
 			temp = jeb->sum_collected->sum_list;
 			jeb->sum_collected->sum_list = jeb->sum_collected->sum_list->u.next;
 			kfree(temp);
 			jeb->sum_collected->sum_num--;
 		}
-		
+
 		if(jeb->sum_collected->sum_num != 0){
 			WARNING_MSG( "Ooops, something wrong happened! sum_num != 0, but sum_list = null ???");
 			jeb->sum_collected->sum_num = 0;
 		}
-	}	
+	}
 }
 
 /* Called from wbuf.c to collect writed node info */
@@ -189,42 +189,42 @@
 int jffs3_sum_add_kvec(struct jffs3_sb_info *c, const struct kvec *invecs, unsigned long count, uint32_t ofs)
 {
 	union jffs3_node_union *node;
-	struct jffs3_eraseblock *jeb;	
+	struct jffs3_eraseblock *jeb;
         int ret;
-	
+
 	node = (union jffs3_node_union *) invecs[0].iov_base;
 	jeb = &c->blocks[ofs / c->sector_size];
         ofs -= jeb->offset;
-       
-        if ((ret=jffs3_sum_care_sum_collected(jeb))) return ret;        
-	
+
+        if ((ret=jffs3_sum_care_sum_collected(jeb))) return ret;
+
 	switch(je16_to_cpu(node->u.nodetype)){
 		case JFFS3_NODETYPE_INODE : {
-			struct jffs3_sum_inode_mem *temp = (struct jffs3_sum_inode_mem *) 
+			struct jffs3_sum_inode_mem *temp = (struct jffs3_sum_inode_mem *)
 				kmalloc(sizeof(struct jffs3_sum_inode_mem), GFP_KERNEL);
-			
+
 			if (!temp)
 				return -ENOMEM;
 
 			temp->nodetype = node->i.nodetype;
 			temp->inode = node->i.ino;
 			temp->version = node->i.version;
-			temp->offset = cpu_to_je32(ofs); 
+			temp->offset = cpu_to_je32(ofs);
 			temp->totlen = node->i.totlen;
 			temp->next = NULL;
-						
+
 			return jffs3_sum_add_mem(jeb, (union jffs3_sum_mem *)temp);
-			
+
 			break;
 		}
-		
+
 		case JFFS3_NODETYPE_DIRENT : {
-			struct jffs3_sum_dirent_mem *temp = (struct jffs3_sum_dirent_mem *) 
+			struct jffs3_sum_dirent_mem *temp = (struct jffs3_sum_dirent_mem *)
 				kmalloc(sizeof(struct jffs3_sum_dirent_mem) + node->d.nsize, GFP_KERNEL);
-			
+
 			if (!temp)
 				return -ENOMEM;
-			
+
 			temp->nodetype = node->d.nodetype;
 			temp->totlen = node->d.totlen;
 			temp->offset = cpu_to_je32(ofs);
@@ -234,37 +234,37 @@
 			temp->nsize = node->d.nsize;
 			temp->type = node->d.type;
 			temp->next = NULL;
-			
+
 			memcpy(temp->name,invecs[1].iov_base,node->d.nsize);
-			
+
 			return jffs3_sum_add_mem(jeb, (union jffs3_sum_mem *)temp);
-			
+
 			break;
 		}
-		
+
 		case JFFS3_NODETYPE_PADDING : {
 			DBG_SUMMARY(1,"Node PADDING\n");
                         jeb->sum_collected->sum_padded += je32_to_cpu(node->u.totlen);
 			break;
 		}
-		
+
 		case JFFS3_NODETYPE_CLEANMARKER : {
 			DBG_SUMMARY(1,"Node CLEANMARKER\n");
 			break;
 		}
-		
+
 		case JFFS3_NODETYPE_SUMMARY : {
 			DBG_SUMMARY(1,"Node SUMMARY\n");
 			break;
 		}
-		
+
 		default : {
 			ERROR_MSG("Node not supported\n");
 			BUG();
 			break;
 		}
 	}
-	
+
 	return 0;
 }
 
@@ -272,33 +272,33 @@
 
 int jffs3_sum_scan_sumnode(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb, uint32_t ofs, uint32_t *pseudo_random)
 {
-	
+
 	struct jffs3_unknown_node crcnode;
 	struct jffs3_raw_node_ref *raw;
 	struct jffs3_raw_node_ref *cache_ref;
 	struct jffs3_inode_cache *ic;
 	struct jffs3_full_dirent *fd;
-		
+
 	int i, err;
 	int bad_sum = 0;
 	int sumsize;
 	uint32_t ino;
 	uint32_t crc;
 	struct jffs3_summary_node *summary;
-		
+
 	sumsize = c->sector_size - ofs;
 	ofs += jeb->offset;
-	
+
 	DBG_SUMMARY(1,"Summary found for 0x%08x at 0x%08x (0x%x bytes)\n", jeb->offset, ofs, sumsize);
-	
+
 	summary = (struct jffs3_summary_node *) kmalloc(sumsize, GFP_KERNEL);
-		
+
 	if (!summary) {
 			return -ENOMEM;
 	}
-	
+
 	err = jffs3_fill_scan_buf(c, (unsigned char *)summary, ofs, sumsize);
-	
+
 	if (err) {
 			kfree(summary);
 			return err;
@@ -309,84 +309,86 @@
 	crcnode.nodetype = cpu_to_je16(JFFS3_NODETYPE_SUMMARY);
 	crcnode.totlen = summary->totlen;
 	crc = crc32(0, &crcnode, sizeof(crcnode)-4);
-	
+
 	if (je32_to_cpu(summary->hdr_crc) != crc) {
 			DBG_SUMMARY(1,"Summary node header is corrupt (bad CRC or no summary at all)\n");
 			bad_sum = 1;
 	}
-	
+
 	if ((!bad_sum) && (je32_to_cpu(summary->totlen) != sumsize)) {
 			DBG_SUMMARY(1,"Summary node is corrupt (wrong erasesize?)\n");
 			bad_sum = 1;
 	}
-	
+
 	crc = crc32(0, summary, sizeof(struct jffs3_summary_node)-8);
-		
+
 	if ((!bad_sum) && (je32_to_cpu(summary->node_crc) != crc)) {
 			DBG_SUMMARY(1,"Summary node is corrupt (bad CRC)\n");
 			bad_sum = 1;
 	}
-	
+
 	crc = crc32(0, summary->sum, sumsize - sizeof(struct jffs3_summary_node));
 
 	if ((!bad_sum) && (je32_to_cpu(summary->sum_crc) != crc)) {
 			DBG_SUMMARY(1,"Summary node data is corrupt (bad CRC)\n");
 			bad_sum = 1;
 	}
-	
+
 	if (!bad_sum) {
-		
+
 		struct jffs3_sum_unknown_flash *sp;
 		sp = (struct jffs3_sum_unknown_flash *) summary->sum;
 
 		if ( je32_to_cpu(summary->cln_mkr) ) {
-			
+
 			DBG_SUMMARY(1,"CLEANMARKER node \n");
-			
+
 			if (je32_to_cpu(summary->cln_mkr) != c->cleanmarker_size) {
-				DBG_SUMMARY(1,"CLEANMARKER node has totlen 0x%x != normal 0x%x\n", 
+				DBG_SUMMARY(1,"CLEANMARKER node has totlen 0x%x != normal 0x%x\n",
 				   je32_to_cpu(summary->cln_mkr), c->cleanmarker_size);
 				UNCHECKED_SPACE( PAD(je32_to_cpu(summary->cln_mkr)) );
-			} 
+			}
 			else if (jeb->first_node) {
 				DBG_SUMMARY(1,"CLEANMARKER node not first node in block (0x%08x)\n", jeb->offset);
 				UNCHECKED_SPACE( PAD(je32_to_cpu(summary->cln_mkr)));
-			} 
+			}
 			else {
 				struct jffs3_raw_node_ref *marker_ref = jffs3_alloc_raw_node_ref();
-					
+
 				if (!marker_ref) {
 					DBG_SUMMARY(1,"Failed to allocate node ref for cleanmarker\n");
 					kfree(summary);
 					return -ENOMEM;
 				}
-				
+
 				marker_ref->next_in_ino = NULL;
 				marker_ref->next_phys = NULL;
 				marker_ref->flash_offset = jeb->offset | REF_NORMAL;
+#ifdef TMP_TOTLEN
 				marker_ref->__totlen = je32_to_cpu(summary->cln_mkr);
+#endif
 				jeb->first_node = jeb->last_node = marker_ref;
-			
+
 				USED_SPACE( PAD(je32_to_cpu(summary->cln_mkr)) );
-								
+
 			}
 		}
 
 		if ( je32_to_cpu(summary->padded) ) {
                         DIRTY_SPACE(je32_to_cpu(summary->padded));
                 }
-		
+
 		for(i = 0; i < je16_to_cpu(summary->sum_num); i++) {
-			
+
 			DBG_SUMMARY(1,"Processing summary information %d\n", i);
 			uint8_t *temp8ptr = NULL;
-			
+
 			switch (je16_to_cpu(sp->nodetype)) {
-				
+
 				case JFFS3_NODETYPE_INODE : {
 					struct jffs3_sum_inode_flash *spi;
 					spi = (struct jffs3_sum_inode_flash *) sp;
-						
+
 					ino = je32_to_cpu(spi->inode);
 					DBG_SUMMARY(1,"Inode at 0x%08x\n", jeb->offset + je32_to_cpu(spi->offset));
 					raw = jffs3_alloc_raw_node_ref();
@@ -395,7 +397,7 @@
 						kfree(summary);
 						return -ENOMEM;
 					}
-		
+
 					ic = jffs3_get_ino_cache(c, ino);
 					if (!ic) {
 						ic = jffs3_scan_make_ino_cache(c, ino);
@@ -406,42 +408,44 @@
 							return -ENOMEM;
 						}
 					}
-						
+
 					raw->flash_offset = (jeb->offset + je32_to_cpu(spi->offset)) | REF_UNCHECKED;
+#ifdef TMP_TOTLEN
 					raw->__totlen = PAD(je32_to_cpu(spi->totlen));
+#endif
 					raw->next_phys = NULL;
 					raw->next_in_ino = ic->nodes;
-						
+
 					ic->nodes = raw;
 					if (!jeb->first_node)
 							jeb->first_node = raw;
 					if (jeb->last_node)
 							jeb->last_node->next_phys = raw;
 					jeb->last_node = raw;
-						
+
 					*pseudo_random += je32_to_cpu(spi->version);
 					UNCHECKED_SPACE(PAD(je32_to_cpu(spi->totlen)));
-					
+
 					temp8ptr = (uint8_t *) sp;
 					temp8ptr += JFFS3_SUMMARY_INODE_SIZE;
 					sp = (struct jffs3_sum_unknown_flash *) temp8ptr;
-					
+
 					break;
 				}
-					
+
 				case JFFS3_NODETYPE_DIRENT : {
 					struct jffs3_sum_dirent_flash *spd;
 					spd = (struct jffs3_sum_dirent_flash *) sp;
-					
+
 					fd = jffs3_alloc_full_dirent(spd->nsize+1);
 					if (!fd) {
 						kfree(summary);
 						return -ENOMEM;
 					}
-					
+
 					memcpy(&fd->name, spd->name, spd->nsize);
 					fd->name[spd->nsize] = 0;
-					
+
 					raw = jffs3_alloc_raw_node_ref();
 					if (!raw) {
 						jffs3_free_full_dirent(fd);
@@ -449,7 +453,7 @@
 						kfree(summary);
 						return -ENOMEM;
 					}
-					
+
 					ic = jffs3_scan_make_ino_cache(c, je32_to_cpu(spd->pino));
 					if (!ic) {
 						jffs3_free_full_dirent(fd);
@@ -457,8 +461,10 @@
 						kfree(summary);
 						return -ENOMEM;
 					}
-					
+
+#ifdef TMP_TOTLEN
 					raw->__totlen = PAD(je32_to_cpu(spd->totlen));
+#endif
 					raw->flash_offset = (jeb->offset + je32_to_cpu(spd->offset)) | REF_PRISTINE;
 					raw->next_phys = NULL;
 					raw->next_in_ino = ic->nodes;
@@ -468,7 +474,7 @@
 					if (jeb->last_node)
 						jeb->last_node->next_phys = raw;
 					jeb->last_node = raw;
-				
+
 					fd->raw = raw;
 					fd->next = NULL;
 					fd->version = je32_to_cpu(spd->version);
@@ -477,45 +483,47 @@
 					fd->type = spd->type;
 					USED_SPACE(PAD(je32_to_cpu(spd->totlen)));
 					jffs3_add_fd_to_list(c, fd, &ic->scan_dents);
-					
+
 					*pseudo_random += je32_to_cpu(spd->version);
-					
+
 					temp8ptr = (uint8_t *) sp;
-					temp8ptr += JFFS3_SUMMARY_DIRENT_SIZE(spd->nsize); 
+					temp8ptr += JFFS3_SUMMARY_DIRENT_SIZE(spd->nsize);
 					sp = (struct jffs3_sum_unknown_flash *) temp8ptr;
-					
+
 					break;
 				}
-				
+
 				default : {
 					WARNING_MSG("Kernel doesn't support this type of node !!! Exiting");
 					return -EIO;
-					break;			
+					break;
 				}
 			}
 		}
-		
+
 		kfree(summary);
 
 		/* for ACCT_PARANOIA_CHECK */
 		cache_ref = jffs3_alloc_raw_node_ref();
-		
+
 		if (!cache_ref) {
 			WARNING_MSG("Failed to allocate node ref for cache\n");
 			return -ENOMEM;
 		}
-		
+
 		cache_ref->next_in_ino = NULL;
 		cache_ref->next_phys = NULL;
 		cache_ref->flash_offset = ofs | REF_NORMAL;
+#ifdef TMP_TOTLEN
 		cache_ref->__totlen = sumsize;
-		
+#endif
+
 		if (!jeb->first_node)
 			jeb->first_node = cache_ref;
 		if (jeb->last_node)
 			jeb->last_node->next_phys = cache_ref;
 		jeb->last_node = cache_ref;
-		
+
 		USED_SPACE(sumsize);
 
                 jeb->wasted_size += jeb->free_size;
@@ -525,26 +533,26 @@
 
 		/* somebody check this and all of space accounting in summary support */
 
-		if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size 
-			&& (!jeb->first_node || !jeb->first_node->next_in_ino) ) { 
-				return BLK_STATE_CLEANMARKER; 
-			}		
-		/* move blocks with max 4 byte dirty space to cleanlist */	
+		if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size
+			&& (!jeb->first_node || !jeb->first_node->next_in_ino) ) {
+				return BLK_STATE_CLEANMARKER;
+			}
+		/* move blocks with max 4 byte dirty space to cleanlist */
 		else if (!ISDIRTY(c->sector_size - (jeb->used_size + jeb->unchecked_size))) {
 			c->dirty_size -= jeb->dirty_size;
-			c->wasted_size += jeb->dirty_size; 
+			c->wasted_size += jeb->dirty_size;
 			jeb->wasted_size += jeb->dirty_size;
 			jeb->dirty_size = 0;
 			return BLK_STATE_CLEAN;
 		}
-		else if (jeb->used_size || jeb->unchecked_size) { 
-				return BLK_STATE_PARTDIRTY; 
+		else if (jeb->used_size || jeb->unchecked_size) {
+				return BLK_STATE_PARTDIRTY;
 		}
-		else { 
-				return BLK_STATE_ALLDIRTY; 
+		else {
+				return BLK_STATE_ALLDIRTY;
 		}
 	}
-	
+
 	return 0;
 }
 
@@ -563,158 +571,158 @@
 	size_t retlen;
 	int ret;
 	struct jffs3_eraseblock *jeb;
-	struct kvec vecs[2];	
+	struct kvec vecs[2];
 	jint32_t magic = cpu_to_je32(JFFS3_SUM_MAGIC);
-		
+
 	DBG_SUMMARY(2,"entering\n");
-	
+
 	jeb = c->nextblock;
-	
+
 	if (!jeb->sum_collected->sum_num || !jeb->sum_collected->sum_list) {
 		ERROR_MSG("empty summary info!!!\n");
-		BUG(); 
+		BUG();
 	}
-	
+
 	datasize = jeb->sum_collected->sum_size + sizeof(struct jffs3_sum_marker);
 	infosize = sizeof(struct jffs3_summary_node) + datasize;
 	padsize = jeb->free_size - infosize;
 	infosize += padsize; datasize += padsize;
 	offset = cpu_to_je32(c->sector_size - jeb->free_size);
-	
+
 	if (padsize < 0) { // if jeb hasn't got enought free space for summary
-		
-		union jffs3_sum_mem *temp;	
-		
+
+		union jffs3_sum_mem *temp;
+
 		while(jeb->sum_collected->sum_list){ //cleanup sum_list
 			temp = jeb->sum_collected->sum_list;
 			jeb->sum_collected->sum_list = jeb->sum_collected->sum_list->u.next;
 			kfree(temp);
 			jeb->sum_collected->sum_num--;
 		}
-		
+
 		jeb->sum_collected->sum_list = NULL;
 		jeb->sum_collected->sum_num = 0;
 		jeb->sum_collected->sum_size = JFFS3_SUMMARY_NOSUM_SIZE; // don't try to write out summary for this node
-		
+
 		WARNING_MSG("not enough space for summary, padsize = %d\n",padsize);
                 return 0;
 	}
-			
+
 	memset(c->summary_buf, 0xff, datasize);
 	memset(&isum, 0, sizeof(isum));
-	
+
 	isum.magic = cpu_to_je16(JFFS3_MAGIC_BITMASK);
 	isum.nodetype = cpu_to_je16(JFFS3_NODETYPE_SUMMARY);
 	isum.totlen = cpu_to_je32(infosize);
 	isum.hdr_crc = cpu_to_je32(crc32(0, &isum, sizeof(struct jffs3_unknown_node) - 4));
         isum.padded = cpu_to_je32(jeb->sum_collected->sum_padded);
-		
+
 	if (c->cleanmarker_size) {
-		isum.cln_mkr = cpu_to_je32(c->cleanmarker_size);	
+		isum.cln_mkr = cpu_to_je32(c->cleanmarker_size);
 	}
 	else{
 		isum.cln_mkr = cpu_to_je32(0);
 	}
-	
+
 	isum.sum_num = cpu_to_je16(jeb->sum_collected->sum_num);
 	wpage = c->summary_buf;
-	
-		
-	while (jeb->sum_collected->sum_num) { // write sum_data 
-		
+
+
+	while (jeb->sum_collected->sum_num) { // write sum_data
+
 
 		switch(je16_to_cpu(jeb->sum_collected->sum_list->u.nodetype)){
-			
+
 			case JFFS3_NODETYPE_INODE : {
 				jint16_t *temp16ptr = (jint16_t *)wpage;
-				
+
 				*(temp16ptr++) = jeb->sum_collected->sum_list->i.nodetype;
 				wpage = (jint32_t *) temp16ptr;
-				
+
 				*(wpage++) = jeb->sum_collected->sum_list->i.inode;
 				*(wpage++) = jeb->sum_collected->sum_list->i.version;
 				*(wpage++) = jeb->sum_collected->sum_list->i.offset;
 				*(wpage++) = jeb->sum_collected->sum_list->i.totlen;
 				break;
 			}
-			
+
 			case JFFS3_NODETYPE_DIRENT : {
 				jint16_t *temp16ptr = (jint16_t *) wpage;
 				uint8_t *temp8ptr = NULL;
-				
+
 				*(temp16ptr++) = jeb->sum_collected->sum_list->d.nodetype;
 				wpage = (jint32_t *) temp16ptr;
-				
+
 				*(wpage++) = jeb->sum_collected->sum_list->d.totlen;
 				*(wpage++) = jeb->sum_collected->sum_list->d.offset;
 				*(wpage++) = jeb->sum_collected->sum_list->d.pino;
 				*(wpage++) = jeb->sum_collected->sum_list->d.version;
 				*(wpage++) = jeb->sum_collected->sum_list->d.ino;
-				
+
 				temp8ptr = (uint8_t *) wpage;
 				*(temp8ptr++) = jeb->sum_collected->sum_list->d.nsize;
 				*(temp8ptr++) = jeb->sum_collected->sum_list->d.type;
-								
+
 				memcpy(temp8ptr,jeb->sum_collected->sum_list->d.name,jeb->sum_collected->sum_list->d.nsize);
 				temp8ptr += jeb->sum_collected->sum_list->d.nsize;
 				wpage = (jint32_t *) temp8ptr;
-				
+
 				break;
 			}
-			
+
 			default : {
 				ERROR_MSG("Unknown node in summary information!!!\n");
 				BUG();
 			}
 		}
-		
+
 		temp = jeb->sum_collected->sum_list;
 		jeb->sum_collected->sum_list = jeb->sum_collected->sum_list->u.next;
 		kfree(temp);
-		
+
 		jeb->sum_collected->sum_num--;
 	}
-	
+
 	jeb->sum_collected->sum_size = 0;
-	
+
 	tempptr = (uint8_t *) wpage;
 	tempptr += padsize;
 	wpage = (jint32_t *) tempptr;
-	
+
 	*(wpage++) = offset;
 	*(wpage++) = cpu_to_je32(c->sector_size);
 	*(wpage++) = magic;
 	isum.sum_crc = cpu_to_je32(crc32(0, c->summary_buf, datasize));
 	isum.node_crc = cpu_to_je32(crc32(0, &isum, sizeof(isum) - 8));
-	
+
 	vecs[0].iov_base = &isum;
 	vecs[0].iov_len = sizeof(isum);
 	vecs[1].iov_base = c->summary_buf;
 	vecs[1].iov_len = datasize;
-			
+
 	DBG_SUMMARY(1,"writing out data to flash to pos : 0x%08x\n",jeb->offset + c->sector_size - jeb->free_size);
-	
+
 	spin_unlock(&c->erase_completion_lock);
 	ret = jffs3_flash_writev(c, vecs, 2, jeb->offset + c->sector_size - jeb->free_size, &retlen, 0);
 	spin_lock(&c->erase_completion_lock);
 
-	
+
 	if (ret || (retlen != infosize)) {
-		WARNING_MSG("write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", 
+		WARNING_MSG("write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
 		      infosize, jeb->offset + c->sector_size - jeb->free_size, ret, retlen);
 
 		jeb->sum_collected->sum_size = JFFS3_SUMMARY_NOSUM_SIZE;
-				
+
 		WASTED_SPACE(infosize);
-		
+
 		return 0;
-	}	
-	
+	}
+
 	/*spin_unlock(&c->erase_completion_lock);
 	jffs3_flush_wbuf_pad(c); // summary filled the wbuf
 	spin_lock(&c->erase_completion_lock);*/
 
 	WASTED_SPACE(infosize);
-	
+
 	return 0;
 }

Index: summary.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/summary.h,v
retrieving revision 3.1
retrieving revision 3.2
diff -u -r3.1 -r3.2
--- summary.h	21 Dec 2004 15:18:51 -0000	3.1
+++ summary.h	25 Dec 2004 11:11:22 -0000	3.2
@@ -12,39 +12,12 @@
  *
  */
 
-#ifndef JFFS3_SUMMARY_H
-#define JFFS3_SUMMARY_H
+#ifndef __JFFS3_SUMMARY_H__
+#define __JFFS3_SUMMARY_H__
 
 #include <linux/uio.h>
 #include "jffs3.h"
-
-#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
-		c->free_size -= _x; c->dirty_size += _x; \
-		jeb->free_size -= _x ; jeb->dirty_size += _x; \
-		}while(0)
-#define USED_SPACE(x) do { typeof(x) _x = (x); \
-		c->free_size -= _x; c->used_size += _x; \
-		jeb->free_size -= _x ; jeb->used_size += _x; \
-		}while(0)
-#define WASTED_SPACE(x) do { typeof(x) _x = (x); \
-		c->free_size -= _x; c->wasted_size += _x; \
-		jeb->free_size -= _x ; jeb->wasted_size += _x; \
-		}while(0)
-#define UNCHECKED_SPACE(x) do { typeof(x) _x = (x); \
-		c->free_size -= _x; c->unchecked_size += _x; \
-		jeb->free_size -= _x ; jeb->unchecked_size += _x; \
-		}while(0)
-
-#define BLK_STATE_ALLFF		0
-#define BLK_STATE_CLEAN		1
-#define BLK_STATE_PARTDIRTY	2
-#define BLK_STATE_CLEANMARKER	3
-#define BLK_STATE_ALLDIRTY	4
-#define BLK_STATE_BADBLOCK	5
-
-#define JFFS3_SUMMARY_NOSUM_SIZE 0xffffffff
-#define JFFS3_SUMMARY_INODE_SIZE (sizeof(struct jffs3_sum_inode_flash))
-#define JFFS3_SUMMARY_DIRENT_SIZE(x) (sizeof(struct jffs3_sum_dirent_flash) + (x))
+#include "scan.h"
 
 struct jffs3_sum_unknown_flash
 {
@@ -76,7 +49,7 @@
 union jffs3_sum_flash{
 	struct jffs3_sum_unknown_flash u;
 	struct jffs3_sum_inode_flash i;
-	struct jffs3_sum_dirent_flash d; 
+	struct jffs3_sum_dirent_flash d;
 };
 
 /* list version of jffs3_sum_*flash for kernel and sumtool */
@@ -84,7 +57,7 @@
 {
 	union jffs3_sum_mem *next;
 	jint16_t nodetype;	/* node type	*/
-	
+
 };
 
 struct jffs3_sum_inode_mem
@@ -111,11 +84,11 @@
 	uint8_t name[0];	/* dirent name */
 } __attribute__((packed));
 
-union jffs3_sum_mem 
+union jffs3_sum_mem
 {
 	struct jffs3_sum_unknown_mem u;
 	struct jffs3_sum_inode_mem i;
-	struct jffs3_sum_dirent_mem d; 
+	struct jffs3_sum_dirent_mem d;
 };
 
 struct jffs3_sum_info
@@ -134,7 +107,7 @@
 };
 
 #define JFFS3_SUMMARY_FRAME_SIZE (sizeof(struct jffs3_summary_node)+sizeof(struct jffs3_sum_marker)+3)
-	
+
 #if !(defined(SUM_TOOL) || defined(JFFS2DUMP))
 
 int jffs3_sum_init(struct jffs3_sb_info *c);
@@ -146,13 +119,13 @@
 void jffs3_sum_clean_all_info(struct jffs3_sb_info *c); /* clean up all summary information in all jeb (umount) */
 
 int jffs3_sum_add_padding_mem(struct jffs3_eraseblock *jeb, uint32_t size);
-int jffs3_sum_add_inode_mem(struct jffs3_eraseblock *jeb, struct jffs3_raw_inode *ri, uint32_t ofs);	
-int jffs3_sum_add_dirent_mem(struct jffs3_eraseblock *jeb, struct jffs3_raw_dirent *rd, uint32_t ofs);	
-int jffs3_sum_add_kvec(struct jffs3_sb_info *c, const struct kvec *invecs, unsigned long count,  uint32_t to);	
+int jffs3_sum_add_inode_mem(struct jffs3_eraseblock *jeb, struct jffs3_raw_inode *ri, uint32_t ofs);
+int jffs3_sum_add_dirent_mem(struct jffs3_eraseblock *jeb, struct jffs3_raw_dirent *rd, uint32_t ofs);
+int jffs3_sum_add_kvec(struct jffs3_sb_info *c, const struct kvec *invecs, unsigned long count,  uint32_t to);
 
 int jffs3_sum_scan_sumnode(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb, uint32_t ofs, uint32_t *pseudo_random);
-int jffs3_sum_write_sumnode(struct jffs3_sb_info *c);	
+int jffs3_sum_write_sumnode(struct jffs3_sb_info *c);
 
 #endif
 
-#endif /* JFFS3_SUMMARY_H */
+#endif /* __JFFS3_SUMMARY_H__ */

Index: super-v24.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/super-v24.c,v
retrieving revision 3.3
retrieving revision 3.4
diff -u -r3.3 -r3.4
--- super-v24.c	23 Dec 2004 18:53:37 -0000	3.3
+++ super-v24.c	25 Dec 2004 11:11:22 -0000	3.4
@@ -116,7 +116,7 @@
 	if (c->mtd->sync)
 		c->mtd->sync(c->mtd);
 	put_mtd_device(c->mtd);
-	
+
 	D1(printk(KERN_DEBUG "jffs3_put_super returning\n"));
 }
 
@@ -132,19 +132,19 @@
 #endif
 #ifdef CONFIG_JFFS3_SUMMARY
 	       " (SUMMARY)"
-#endif	
+#endif
 	       " (C) 2001-2004 Red Hat, Inc.\n");
 
 #ifdef JFFS3_OUT_OF_KERNEL
 	/* sanity checks. Could we do these at compile time? */
 	if (sizeof(struct jffs3_sb_info) > sizeof (((struct super_block *)NULL)->u)) {
-		printk(KERN_ERR "JFFS3 error: struct jffs3_sb_info (%d bytes) doesn't fit in the super_block union (%d bytes)\n", 
+		printk(KERN_ERR "JFFS3 error: struct jffs3_sb_info (%d bytes) doesn't fit in the super_block union (%d bytes)\n",
 		       sizeof(struct jffs3_sb_info), sizeof (((struct super_block *)NULL)->u));
 		return -EIO;
 	}
 
 	if (sizeof(struct jffs3_inode_info) > sizeof (((struct inode *)NULL)->u)) {
-		printk(KERN_ERR "JFFS3 error: struct jffs3_inode_info (%d bytes) doesn't fit in the inode union (%d bytes)\n", 
+		printk(KERN_ERR "JFFS3 error: struct jffs3_inode_info (%d bytes) doesn't fit in the inode union (%d bytes)\n",
 		       sizeof(struct jffs3_inode_info), sizeof (((struct inode *)NULL)->u));
 		return -EIO;
 	}
@@ -186,5 +186,5 @@
 
 MODULE_DESCRIPTION("The Journalling Flash File System, v2");
 MODULE_AUTHOR("Red Hat, Inc.");
-MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for 
+MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for
 		       // the sake of this tag. It's Free Software.

Index: super.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/super.c,v
retrieving revision 3.5
retrieving revision 3.6
diff -u -r3.5 -r3.6
--- super.c	21 Dec 2004 15:18:51 -0000	3.5
+++ super.c	25 Dec 2004 11:11:22 -0000	3.6
@@ -63,7 +63,7 @@
 
 	down(&c->alloc_sem);
 	jffs3_flush_wbuf_pad(c);
-	up(&c->alloc_sem);	
+	up(&c->alloc_sem);
 	return 0;
 }
 
@@ -113,7 +113,7 @@
 }
 
 static struct super_block *jffs3_get_sb_mtd(struct file_system_type *fs_type,
-					      int flags, const char *dev_name, 
+					      int flags, const char *dev_name,
 					      void *data, struct mtd_info *mtd)
 {
 	struct super_block *sb;
@@ -152,7 +152,7 @@
 		deactivate_super(sb);
 		return ERR_PTR(ret);
 	}
-	
+
 #ifdef CONFIG_JFFS3_SUMMARY
         jffs3_sum_init(c);
 #endif
@@ -167,7 +167,7 @@
 }
 
 static struct super_block *jffs3_get_sb_mtdnr(struct file_system_type *fs_type,
-					      int flags, const char *dev_name, 
+					      int flags, const char *dev_name,
 					      void *data, int mtdnr)
 {
 	struct mtd_info *mtd;
@@ -196,7 +196,7 @@
 
 	/* The preferred way of mounting in future; especially when
 	   CONFIG_BLK_DEV is implemented - we specify the underlying
-	   MTD device by number or by name, so that we don't require 
+	   MTD device by number or by name, so that we don't require
 	   block device support to be present in the kernel. */
 
 	/* FIXME: How to do the root fs this way? */
@@ -220,7 +220,7 @@
 		} else if (isdigit(dev_name[3])) {
 			/* Mount by MTD device number name */
 			char *endptr;
-			
+
 			mtdnr = simple_strtoul(dev_name+3, &endptr, 0);
 			if (!*endptr) {
 				/* It was a valid number */
@@ -230,7 +230,7 @@
 		}
 	}
 
-	/* Try the old way - the hack where we allowed users to mount 
+	/* Try the old way - the hack where we allowed users to mount
 	   /dev/mtdblock$(n) but didn't actually _use_ the blkdev */
 
 	err = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
@@ -320,7 +320,7 @@
 #endif
 #ifdef CONFIG_JFFS3_SUMMARY
            " (SUMMARY) "
-#endif	
+#endif
 	       " (C) 2001-2004 Red Hat, Inc.\n");
 
 	jffs3_inode_cachep = kmem_cache_create("jffs3_i",
@@ -370,5 +370,5 @@
 
 MODULE_DESCRIPTION("The Journalling Flash File System, v3");
 MODULE_AUTHOR("Red Hat, Inc.");
-MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for 
+MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for
 		       // the sake of this tag. It's Free Software.

Index: symlink-v24.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/symlink-v24.c,v
retrieving revision 3.1
retrieving revision 3.2
diff -u -r3.1 -r3.2
--- symlink-v24.c	9 Dec 2004 16:05:07 -0000	3.1
+++ symlink-v24.c	25 Dec 2004 11:11:22 -0000	3.2
@@ -22,7 +22,7 @@
 int jffs3_follow_link(struct dentry *dentry, struct nameidata *nd);
 
 struct inode_operations jffs3_symlink_inode_operations =
-{	
+{
 	.readlink =	jffs3_readlink,
 	.follow_link =	jffs3_follow_link,
 	.setattr =	jffs3_setattr

Index: symlink.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/symlink.c,v
retrieving revision 3.1
retrieving revision 3.2
diff -u -r3.1 -r3.2
--- symlink.c	9 Dec 2004 16:05:07 -0000	3.1
+++ symlink.c	25 Dec 2004 11:11:22 -0000	3.2
@@ -23,7 +23,7 @@
 static void jffs3_put_link(struct dentry *dentry, struct nameidata *nd);
 
 struct inode_operations jffs3_symlink_inode_operations =
-{	
+{
 	.readlink =	generic_readlink,
 	.follow_link =	jffs3_follow_link,
 	.put_link =	jffs3_put_link,

Index: wbuf.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/wbuf.c,v
retrieving revision 3.7
retrieving revision 3.8
diff -u -r3.7 -r3.8
--- wbuf.c	23 Dec 2004 18:53:37 -0000	3.7
+++ wbuf.c	25 Dec 2004 11:11:22 -0000	3.8
@@ -20,14 +20,7 @@
 #include <linux/crc32.h>
 #include <linux/mtd/nand.h>
 #include "nodelist.h"
-
-/* For testing write failures */
-#undef BREAKME
-#undef BREAKMEHEADER
-
-#ifdef BREAKME
-static unsigned char *brokenbuf;
-#endif
+#include "summary.h"
 
 /* max. erase failures before we mark a block bad */
 #define MAX_ERASE_FAILURES 	2
@@ -192,7 +185,7 @@
 	/* Find the first node to be recovered, by skipping over every
 	   node which ends before the wbuf starts, or which is obsolete. */
 	first_raw = &jeb->first_node;
-	while (*first_raw && 
+	while (*first_raw &&
 	       (ref_obsolete(*first_raw) ||
 		(ref_offset(*first_raw)+ref_totlen(c, jeb, *first_raw)) < c->wbuf_ofs)) {
 		DBG_WBUF(1, "Skipping node at 0x%08x(%d)-0x%08x which is either before 0x%08x or obsolete\n",
@@ -239,7 +232,7 @@
 			ret = c->mtd->read_ecc(c->mtd, start, c->wbuf_ofs - start, &retlen, buf, NULL, c->oobinfo);
 		else
 			ret = c->mtd->read(c->mtd, start, c->wbuf_ofs - start, &retlen, buf);
-		
+
 		if (ret == -EBADMSG && retlen == c->wbuf_ofs - start) {
 			/* ECC recovered */
 			ret = 0;
@@ -285,17 +278,7 @@
 
 		DBG_WBUF(1, "Write 0x%x bytes at 0x%08x in wbuf recover\n",
 			  towrite, ofs);
-	  
-#ifdef BREAKMEHEADER
-		static int breakme;
-		if (breakme++ == 20) {
-			WARNING_MSG("Faking write error at 0x%08x\n", ofs);
-			breakme = 0;
-			c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen,
-					  brokenbuf, NULL, c->oobinfo);
-			ret = -EIO;
-		} else
-#endif
+
 		if (jffs3_cleanmarker_oob(c))
 			ret = c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen,
 						buf, NULL, c->oobinfo);
@@ -309,17 +292,20 @@
 
 			if (retlen) {
 				struct jffs3_raw_node_ref *raw2;
+				uint32_t rawlen = ref_totlen(c, jeb, *first_raw);
 
 				raw2 = jffs3_alloc_raw_node_ref();
 				if (!raw2)
 					return;
 
 				raw2->flash_offset = ofs | REF_OBSOLETE;
-				raw2->__totlen = ref_totlen(c, jeb, *first_raw);
+#ifdef TMP_TOTLEN
+				raw2->__totlen = rawlen;
+#endif
 				raw2->next_phys = NULL;
 				raw2->next_in_ino = NULL;
 
-				jffs3_add_physical_node_ref(c, raw2);
+				jffs3_add_physical_node_ref(c, raw2, rawlen);
 			}
 			return;
 		}
@@ -425,10 +411,17 @@
 	if (jffs3_can_mark_obsolete(c))
 		return 0;
 
-	if (!down_trylock(&c->alloc_sem)) {
-		up(&c->alloc_sem);
-		ERROR_MSG("jffs3_flush_wbuf() called with alloc_sem not locked!\n");
-		BUG();
+	DBG_WBUF(2, "pad %d, wbuf_ofs %#08x, wbuf_len %#x, to pad %#x\n", pad,
+			c->wbuf_ofs, c->wbuf_len, c->wbuf_pagesize - c->wbuf_len);
+
+	if (PARANOIA) {
+		if (!down_trylock(&c->alloc_sem)) {
+			up(&c->alloc_sem);
+			ERROR_MSG("Called with alloc_sem not locked!\n");
+			BUG();
+		}
+	} else {
+		down(&c->alloc_sem);
 	}
 
 	if(!c->wbuf || !c->wbuf_len)
@@ -438,7 +431,7 @@
 	   this happens, if we have a change to a new block,
 	   or if fsync forces us to flush the writebuffer.
 	   if we have a switch to next page, we will not have
-	   enough remaining space for this. 
+	   enough remaining space for this.
 	*/
 	if (pad) {
 		c->wbuf_len = PAD(c->wbuf_len);
@@ -446,7 +439,7 @@
 		/* Pad with JFFS3_DIRTY_BITMASK initially.  this helps out ECC'd NOR
 		   with 8 byte page size */
 		memset(c->wbuf + c->wbuf_len, 0, c->wbuf_pagesize - c->wbuf_len);
-		
+
 		if ( c->wbuf_len + sizeof(struct jffs3_unknown_node) < c->wbuf_pagesize) {
 			struct jffs3_unknown_node *padnode = (void *)(c->wbuf + c->wbuf_len);
 			padnode->magic = cpu_to_je16(JFFS3_MAGIC_BITMASK);
@@ -457,18 +450,7 @@
 	}
 	/* else jffs3_flash_writev has actually filled in the rest of the
 	   buffer for us, and will deal with the node refs etc. later. */
-	
-#ifdef BREAKME
-	static int breakme;
-	if (breakme++ == 20) {
-		WARNING_MSG("Faking write error at 0x%08x\n", c->wbuf_ofs);
-		breakme = 0;
-		c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize,
-					&retlen, brokenbuf, NULL, c->oobinfo);
-		ret = -EIO;
-	} else 
-#endif
-	
+
 	if (jffs3_cleanmarker_oob(c))
 		ret = c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf, NULL, c->oobinfo);
 	else
@@ -487,40 +469,43 @@
 		return ret;
 	}
 
-	spin_lock(&c->erase_completion_lock);
-
 	/* Adjust free size of the block if we padded. */
-	if (pad) {
-		struct jffs3_eraseblock *jeb;
-
-		jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
-
-		DBG_WBUF(1, "adjusting free_size of %sblock at %08x\n",
-			  (jeb==c->nextblock)?"next":"", jeb->offset);
+	if (pad && c->wbuf_len < c->wbuf_pagesize) {
+		struct jffs3_raw_node_ref *ref;
 
-		jffs3_dbg_wbuf_acct_sanity_check(c, jeb);
+		jffs3_dbg_wbuf_acct_sanity_check(c, &c->blocks[c->wbuf_ofs / c->sector_size]);
 
-		jeb->free_size -= (c->wbuf_pagesize - c->wbuf_len);
-		c->free_size -= (c->wbuf_pagesize - c->wbuf_len);
-		jeb->wasted_size += (c->wbuf_pagesize - c->wbuf_len);
-		c->wasted_size += (c->wbuf_pagesize - c->wbuf_len);
+		ref = jffs3_alloc_raw_node_ref();
+		if (!ref)
+			return -ENOMEM;
+
+		ref->flash_offset = PAD(c->wbuf_ofs + c->wbuf_len) | REF_OBSOLETE;
+#ifdef TMP_TOTLEN
+		ref->__totlen = c->wbuf_pagesize - c->wbuf_len;
+#endif
+		ref->next_in_ino = NULL;
+		ref->next_phys = NULL;
+		DBG_WBUF(1, "Add padding node of length %#x to the node_refs list\n",
+				c->wbuf_pagesize - c->wbuf_len);
+		jffs3_add_physical_node_ref(c, ref, c->wbuf_pagesize - c->wbuf_len);
 	}
 
 	/* Stick any now-obsoleted blocks on the erase_pending_list */
+	spin_lock(&c->erase_completion_lock);
 	jffs3_refile_wbuf_blocks(c);
 	jffs3_clear_wbuf_ino_list(c);
 	spin_unlock(&c->erase_completion_lock);
 
-	memset(c->wbuf,0xff,c->wbuf_pagesize);
+	memset(c->wbuf, 0xff, c->wbuf_pagesize);
 	/* adjust write buffer offset, else we get a non contiguous write bug */
 	c->wbuf_ofs += c->wbuf_pagesize;
 	c->wbuf_len = 0;
 	return 0;
 }
 
-/* Trigger garbage collection to flush the write-buffer. 
+/* Trigger garbage collection to flush the write-buffer.
    If ino arg is zero, do it if _any_ real (i.e. not GC) writes are
-   outstanding. If ino arg non-zero, do it only if a write for the 
+   outstanding. If ino arg non-zero, do it only if a write for the
    given inode is outstanding. */
 int jffs3_flush_wbuf_gc(struct jffs3_sb_info *c, uint32_t ino)
 {
@@ -601,20 +586,20 @@
 	/* If not NAND flash, don't bother */
 	if (!c->wbuf){
 #ifdef CONFIG_JFFS3_SUMMARY
-		DBG_SUMMARY(1,"JFFS3.summary: NOT NAND MEMORY\n");
+		DBG_SUMMARY(1,"NOT NAND MEMORY\n");
 		if(jffs3_sum_add_kvec(c,invecs,count,(uint32_t) to)){
-			ERROR_MSG("jffs3_sum_add_kvec(): MEMORY ALLOCATION ERROR!");
-		}	
-#endif			
+			ERROR_MSG("Can't allocate memory\n");
+		}
+#endif
 		return jffs3_flash_direct_writev(c, invecs, count, to, retlen);
 	}
-	
+
 	down_write(&c->wbuf_sem);
 
 	/* If wbuf_ofs is not initialized, set it to target address */
 	if (c->wbuf_ofs == 0xFFFFFFFF) {
 		c->wbuf_ofs = PAGE_DIV(to);
-		c->wbuf_len = PAGE_MOD(to);			
+		c->wbuf_len = PAGE_MOD(to);
 		memset(c->wbuf,0xff,c->wbuf_pagesize);
 	}
 
@@ -628,10 +613,10 @@
 			memset(c->wbuf,0xff,c->wbuf_pagesize);
 		}
 	}
-	
-	/* Sanity checks on target address. 
-	   It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs), 
-	   and it's permitted to write at the beginning of a new 
+
+	/* Sanity checks on target address.
+	   It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs),
+	   and it's permitted to write at the beginning of a new
 	   erase block. Anything else, and you die.
 	   New block starts at xxx000c (0-b = block header)
 	*/
@@ -649,10 +634,10 @@
 		}
 		/* set pointer to new block */
 		c->wbuf_ofs = PAGE_DIV(to);
-		c->wbuf_len = PAGE_MOD(to);			
-	} 
+		c->wbuf_len = PAGE_MOD(to);
+	}
 
-	if (to != PAD(c->wbuf_ofs + c->wbuf_len)) {
+	if (SANITY && to != PAD(c->wbuf_ofs + c->wbuf_len)) {
 		/* We're not writing immediately after the writebuffer. Bad. */
 		ERROR_MSG("Non-contiguous write to %08lx\n", (unsigned long)to);
 		if (c->wbuf_len)
@@ -670,21 +655,21 @@
 	invec = 0;
 	outvec = 0;
 
-	/* Fill writebuffer first, if already in use */	
+	/* Fill writebuffer first, if already in use */
 	if (c->wbuf_len) {
 		uint32_t invec_ofs = 0;
 
-		/* adjust alignment offset */ 
+		/* adjust alignment offset */
 		if (c->wbuf_len != PAGE_MOD(to)) {
 			c->wbuf_len = PAGE_MOD(to);
 			/* take care of alignment to next page */
 			if (!c->wbuf_len)
 				c->wbuf_len = c->wbuf_pagesize;
 		}
-		
+
 		while(c->wbuf_len < c->wbuf_pagesize) {
 			uint32_t thislen;
-			
+
 			if (invec == count)
 				goto alldone;
 
@@ -692,17 +677,17 @@
 
 			if (thislen >= invecs[invec].iov_len)
 				thislen = invecs[invec].iov_len;
-	
+
 			invec_ofs = thislen;
 
 			memcpy(c->wbuf + c->wbuf_len, invecs[invec].iov_base, thislen);
 			c->wbuf_len += thislen;
 			donelen += thislen;
 			/* Get next invec, if actual did not fill the buffer */
-			if (c->wbuf_len < c->wbuf_pagesize) 
+			if (c->wbuf_len < c->wbuf_pagesize)
 				invec++;
-		}			
-		
+		}
+
 		/* write buffer is full, flush buffer */
 		ret = __jffs3_flush_wbuf(c, NOPAD);
 		if (ret) {
@@ -761,18 +746,18 @@
 
 		/* We did cross a page boundary, so we write some now */
 		if (jffs3_cleanmarker_oob(c))
-			ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, c->oobinfo); 
+			ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, c->oobinfo);
 		else
 			ret = jffs3_flash_direct_writev(c, outvecs, splitvec+1, outvec_to, &wbuf_retlen);
-		
+
 		if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) {
 			/* At this point we have no problem,
-			   c->wbuf is empty. 
+			   c->wbuf is empty.
 			*/
 			*retlen = donelen;
 			goto exit;
 		}
-		
+
 		donelen += wbuf_retlen;
 		c->wbuf_ofs = PAGE_DIV(outvec_to) + PAGE_DIV(totlen);
 
@@ -805,7 +790,7 @@
 	   remember that the wbuf affects this ino */
 alldone:
 	*retlen = donelen;
-	
+
 #ifdef CONFIG_JFFS3_SUMMARY
 	if(jffs3_sum_add_kvec(c,invecs,count,(uint32_t) to)){
 		ERROR_MSG("jffs3_sum_add_kvec(): MEMORY ALLOCATION ERROR!");
@@ -816,7 +801,7 @@
 		jffs3_wbuf_dirties_inode(c, ino);
 
 	ret = 0;
-	
+
 exit:
 	up_write(&c->wbuf_sem);
 	return ret;
@@ -857,18 +842,18 @@
 
 		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 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  
+			 * 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);
 
@@ -877,7 +862,7 @@
 		goto exit;
 
 	/* if we read in a different block, return */
-	if ( (ofs & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) 
+	if ( (ofs & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) )
 		goto exit;
 
 	if (ofs >= c->wbuf_ofs) {
@@ -885,16 +870,16 @@
 		if (owbf > c->wbuf_len)		/* is read beyond write buffer ? */
 			goto exit;
 		lwbf = c->wbuf_len - owbf;	/* number of bytes to copy */
-		if (lwbf > len)	
+		if (lwbf > len)
 			lwbf = len;
-	} else {	
+	} else {
 		orbf = (c->wbuf_ofs - ofs);	/* offset in read buffer */
 		if (orbf > len)			/* is write beyond write buffer ? */
 			goto exit;
 		lwbf = len - orbf; 		/* number of bytes to copy */
-		if (lwbf > c->wbuf_len)	
+		if (lwbf > c->wbuf_len)
 			lwbf = c->wbuf_len;
-	}	
+	}
 	if (lwbf > 0)
 		memcpy(buf+orbf,c->wbuf+owbf,lwbf);
 
@@ -922,7 +907,7 @@
 		WARNING_MSG("Allocation of temporary data buffer for oob check failed\n");
 		return -ENOMEM;
 	}
-	/* 
+	/*
 	 * if mode = 0, we scan for a total empty oob area, else we have
 	 * to take care of the cleanmarker in the first page of the block
 	*/
@@ -931,40 +916,40 @@
 		WARNING_MSG("Read OOB failed %d for block at %08x\n", ret, jeb->offset);
 		goto out;
 	}
-	
+
 	if (retlen < len) {
 		 WARNING_MSG("jffs3_check_oob_empty(): Read OOB return short read "
 			  "(%zd bytes not %d) for block at %08x\n", retlen, len, jeb->offset);
 		ret = -EIO;
 		goto out;
 	}
-	
+
 	/* Special check for first page */
 	for(i = 0; i < oob_size ; i++) {
 		/* Yeah, we know about the cleanmarker. */
-		if (mode && i >= c->fsdata_pos && 
+		if (mode && i >= c->fsdata_pos &&
 		    i < c->fsdata_pos + c->fsdata_len)
 			continue;
 
 		if (buf[i] != 0xFF) {
 			DBG_WBUF(2, "Found %02x at %x in OOB for %08x\n", buf[i], i, jeb->offset);
-			ret = 1; 
+			ret = 1;
 			goto out;
 		}
 	}
 
-	/* we know, we are aligned :) */	
+	/* we know, we are aligned :) */
 	for (page = oob_size; page < len; page += sizeof(long)) {
 		unsigned long dat = *(unsigned long *)(&buf[page]);
 		if(dat != -1) {
-			ret = 1; 
+			ret = 1;
 			goto out;
 		}
 	}
 
 out:
-	kfree(buf);	
-	
+	kfree(buf);
+
 	return ret;
 }
 
@@ -1046,7 +1031,7 @@
 	n.totlen = cpu_to_je32(8);
 
 	ret = jffs3_flash_write_oob(c, jeb->offset + c->fsdata_pos, c->fsdata_len, &retlen, (unsigned char *)&n);
-	
+
 	if (ret) {
 		WARNING_MSG("Write failed for block at %08x: error %d\n", jeb->offset, ret);
 		return ret;
@@ -1058,7 +1043,7 @@
 	return 0;
 }
 
-/* 
+/*
  * On NAND we try to mark this block bad. If the block was erased more
  * than MAX_ERASE_FAILURES we mark it finaly bad.
  * Don't care about failures. This block remains on the erase-pending
@@ -1079,7 +1064,7 @@
 
 	NOTICE_MSG("jffs3_write_nand_badblock(): Marking bad block at %08x\n", bad_offset);
 	ret = c->mtd->block_markbad(c->mtd, bad_offset);
-	
+
 	if (ret) {
 		WARNING_MSG("Write failed for block at %08x: error %d\n", jeb->offset, ret);
 		return ret;
@@ -1103,7 +1088,7 @@
 	/* Do this only, if we have an oob buffer */
 	if (!c->mtd->oobsize)
 		return 0;
-	
+
 	/* Cleanmarker is out-of-band, so inline size zero */
 	c->cleanmarker_size = 0;
 
@@ -1129,7 +1114,7 @@
 			c->fsdata_len = NAND_JFFS3_OOB16_FSDALEN;
 			c->badblock_pos = 15;
 			break;
-	
+
 		default:
 			DBG_WBUF(1, "JFFS3 on NAND. No autoplacment info found\n");
 			return -EINVAL;
@@ -1146,22 +1131,13 @@
 	init_rwsem(&c->wbuf_sem);
 	c->wbuf_pagesize = c->mtd->oobblock;
 	c->wbuf_ofs = 0xFFFFFFFF;
-	
+
 	c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
 	if (!c->wbuf)
 		return -ENOMEM;
 
 	res = jffs3_nand_set_oobinfo(c);
 
-#ifdef BREAKME
-	if (!brokenbuf)
-		brokenbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
-	if (!brokenbuf) {
-		kfree(c->wbuf);
-		return -ENOMEM;
-	}
-	memset(brokenbuf, 0xdb, c->wbuf_pagesize);
-#endif
 	return res;
 }
 

Index: write.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/write.c,v
retrieving revision 3.7
retrieving revision 3.8
diff -u -r3.7 -r3.8
--- write.c	23 Dec 2004 18:53:37 -0000	3.7
+++ write.c	25 Dec 2004 11:11:22 -0000	3.8
@@ -20,6 +20,7 @@
 #include <linux/mtd/mtd.h>
 #include "nodelist.h"
 #include "compr.h"
+#include "summary.h"
 
 int jffs3_do_new_inode(struct jffs3_sb_info *c, struct jffs3_inode_info *f, uint32_t mode, struct jffs3_raw_inode *ri)
 {
@@ -56,7 +57,7 @@
 }
 
 
-/* jffs3_write_dnode - given a raw_inode, allocate a full_dnode for it, 
+/* jffs3_write_dnode - given a raw_inode, allocate a full_dnode for it,
    write it to the flash, link it into the existing inode/fragment list */
 struct jffs3_full_dnode *jffs3_write_dnode(struct jffs3_sb_info *c, struct jffs3_inode_info *f, struct jffs3_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode)
 
@@ -68,11 +69,16 @@
 	int ret;
 	int retried = 0;
 	unsigned long cnt = 2;
+	uint32_t rawlen = PAD(sizeof(*ri) + datalen);
 
-	if(PARANOIA && je32_to_cpu(ri->hdr_crc) != crc32(0, ri, sizeof(struct jffs3_unknown_node)-4)) {
+	DBG_WRITE(1, "Write inode node to %#08x, totlen %#x, datalen %#x\n",
+			flash_ofs, rawlen, datalen);
+
+	if (PARANOIA && je32_to_cpu(ri->hdr_crc) != crc32(0, ri, sizeof(struct jffs3_unknown_node)-4)) {
 		ERROR_MSG("Eep. CRC not correct\n");
 		BUG();
 	};
+
 	vecs[0].iov_base = ri;
 	vecs[0].iov_len = sizeof(*ri);
 	vecs[1].iov_base = (unsigned char *)data;
@@ -89,7 +95,7 @@
 	raw = jffs3_alloc_raw_node_ref();
 	if (!raw)
 		return ERR_PTR(-ENOMEM);
-	
+
 	fn = jffs3_alloc_full_dnode();
 	if (!fn) {
 		jffs3_free_raw_node_ref(raw);
@@ -105,16 +111,17 @@
 		cnt = 1;
  retry:
 	fn->raw = raw;
-
 	raw->flash_offset = flash_ofs;
-	raw->__totlen = PAD(sizeof(*ri)+datalen);
+#ifdef TMP_TOTLEN
+	raw->__totlen = rawlen;
+#endif
 	raw->next_phys = NULL;
 
 	ret = jffs3_flash_writev(c, vecs, cnt, flash_ofs, &retlen,
 				 (alloc_mode==ALLOC_GC)?0:f->inocache->ino);
 
 	if (ret || (retlen != sizeof(*ri) + datalen)) {
-		WARNING_MSG("Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", 
+		WARNING_MSG("Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
 		       sizeof(*ri)+datalen, flash_ofs, ret, retlen);
 
 		/* Mark the space as dirtied */
@@ -122,13 +129,13 @@
 			/* Doesn't belong to any inode */
 			raw->next_in_ino = NULL;
 
-			/* Don't change raw->size to match retlen. We may have 
+			/* Don't change raw->size to match retlen. We may have
 			   written the node header already, and only the data will
 			   seem corrupted, in which case the scan would skip over
-			   any node we write before the original intended end of 
+			   any node we write before the original intended end of
 			   this node */
 			raw->flash_offset |= REF_OBSOLETE;
-			jffs3_add_physical_node_ref(c, raw);
+			jffs3_add_physical_node_ref(c, raw, rawlen);
 			jffs3_mark_node_obsolete(c, raw);
 		} else {
 			WARNING_MSG("Not marking the space at 0x%08x as dirty because "
@@ -143,7 +150,7 @@
 			retried = 1;
 
 			DBG_WRITE(1, "Retrying failed write.\n");
-			
+
 			jffs3_dbg_acct_sanity_check(c, jeb);
 			if (PARANOIA)
 				jffs3_dbg_acct_paranoia_check(c, jeb);
@@ -154,7 +161,7 @@
 				/* Locking pain */
 				up(&f->sem);
 				jffs3_complete_reservation(c);
-			
+
 				ret = jffs3_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, &dummy, alloc_mode, JFFS3_SUMMARY_INODE_SIZE);
 				down(&f->sem);
 			}
@@ -176,9 +183,9 @@
 		return ERR_PTR(ret?ret:-EIO);
 	}
 	/* Mark the space used */
-	/* If node covers at least a whole page, or if it starts at the 
-	   beginning of a page and runs to the end of the file, or if 
-	   it's a hole node, mark it REF_PRISTINE, else REF_NORMAL. 
+	/* If node covers at least a whole page, or if it starts at the
+	   beginning of a page and runs to the end of the file, or if
+	   it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
 	*/
 	if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) ||
 	    ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) &&
@@ -187,7 +194,7 @@
 	} else {
 		raw->flash_offset |= REF_NORMAL;
 	}
-	jffs3_add_physical_node_ref(c, raw);
+	jffs3_add_physical_node_ref(c, raw, rawlen);
 
 	/* Link into per-inode list */
 	spin_lock(&c->erase_completion_lock);
@@ -197,7 +204,7 @@
 
 	DBG_WRITE(1, "wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, "
 		"node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n",
-		flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize), 
+		flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize),
 		je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc),
 		je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen));
 
@@ -215,9 +222,10 @@
 	size_t retlen;
 	struct kvec vecs[2];
 	int retried = 0;
+	uint32_t rawlen = PAD(sizeof(*rd) + namelen);
 	int ret;
 
-	DBG_WRITE(1, "entering, ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x\n", 
+	DBG_WRITE(1, "entering, ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x\n",
 		  je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino),
 		  je32_to_cpu(rd->name_crc));
 
@@ -232,7 +240,7 @@
 	vecs[1].iov_len = namelen;
 	if (PARANOIA)
 		jffs3_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
-	
+
 	raw = jffs3_alloc_raw_node_ref();
 
 	if (!raw)
@@ -253,21 +261,22 @@
 
  retry:
 	fd->raw = raw;
-
 	raw->flash_offset = flash_ofs;
-	raw->__totlen = PAD(sizeof(*rd)+namelen);
+#ifdef TMP_TOTLEN
+	raw->__totlen = rawlen;
+#endif
 	raw->next_phys = NULL;
 
 	ret = jffs3_flash_writev(c, vecs, 2, flash_ofs, &retlen,
 				 (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino));
 	if (ret || (retlen != sizeof(*rd) + namelen)) {
-		WARNING_MSG("Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", 
+		WARNING_MSG("Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
 				sizeof(*rd)+namelen, flash_ofs, ret, retlen);
 		/* Mark the space as dirtied */
 		if (retlen) {
 			raw->next_in_ino = NULL;
 			raw->flash_offset |= REF_OBSOLETE;
-			jffs3_add_physical_node_ref(c, raw);
+			jffs3_add_physical_node_ref(c, raw, rawlen);
 			jffs3_mark_node_obsolete(c, raw);
 		} else {
 			WARNING_MSG("Not marking the space at 0x%08x as dirty because "
@@ -293,7 +302,7 @@
 				/* Locking pain */
 				up(&f->sem);
 				jffs3_complete_reservation(c);
-			
+
 				ret = jffs3_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, &dummy, alloc_mode, JFFS3_SUMMARY_DIRENT_SIZE(namelen));
 				down(&f->sem);
 			}
@@ -314,7 +323,7 @@
 	}
 	/* Mark the space used */
 	raw->flash_offset |= REF_PRISTINE;
-	jffs3_add_physical_node_ref(c, raw);
+	jffs3_add_physical_node_ref(c, raw, rawlen);
 
 	spin_lock(&c->erase_completion_lock);
 	raw->next_in_ino = f->inocache->nodes;
@@ -332,15 +341,15 @@
    we don't have to go digging in struct inode or its equivalent. It should set:
    mode, uid, gid, (starting)isize, atime, ctime, mtime */
 int jffs3_write_inode_range(struct jffs3_sb_info *c, struct jffs3_inode_info *f,
-			    struct jffs3_raw_inode *ri, unsigned char *buf, 
+			    struct jffs3_raw_inode *ri, unsigned char *buf,
 			    uint32_t offset, uint32_t writelen, uint32_t *retlen)
 {
 	int ret = 0;
 	uint32_t writtenlen = 0;
 
-       	DBG_WRITE(1, "Ino #%u, ofs 0x%x, len 0x%x\n",
+       	DBG_WRITE(1, "Inode #%u, ofs %#x, len %#x\n",
 		  f->inocache->ino, offset, writelen);
-		
+
 	while(writelen) {
 		struct jffs3_full_dnode *fn;
 		unsigned char *comprbuf = NULL;
@@ -350,7 +359,7 @@
 		int retried = 0;
 
 	retry:
-		DBG_WRITE(2, "loop: 0x%x to write to 0x%x\n", writelen, offset);
+		DBG_WRITE(2, "Loop: %#x to write to %#x\n", writelen, offset);
 
 		ret = jffs3_reserve_space(c, sizeof(*ri) + JFFS3_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_INODE_SIZE);
 		if (ret) {
@@ -436,11 +445,10 @@
 	uint32_t alloclen, phys_ofs;
 	int ret;
 
-	/* Try to reserve enough space for both node and dirent. 
-	 * Just the node will do for now, though 
+	/* Try to reserve enough space for both node and dirent.
+	 * Just the node will do for now, though
 	 */
 	ret = jffs3_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_INODE_SIZE);
-	DBG_WRITE(1, "reserved 0x%x bytes\n", alloclen);
 	if (ret) {
 		up(&f->sem);
 		return ret;
@@ -451,8 +459,8 @@
 
 	fn = jffs3_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
 
-	DBG_WRITE(1, "created file with mode 0x%x\n",
-		  jemode_to_cpu(ri->mode));
+	DBG_WRITE(1, "Created file with mode %#x\n",
+			jemode_to_cpu(ri->mode));
 
 	if (IS_ERR(fn)) {
 		DBG_WRITE(1, "failed\n");
@@ -461,7 +469,7 @@
 		jffs3_complete_reservation(c);
 		return PTR_ERR(fn);
 	}
-	/* No data here. Only a metadata node, which will be 
+	/* No data here. Only a metadata node, which will be
 	   obsoleted by the first data write
 	*/
 	f->metadata = fn;
@@ -469,7 +477,7 @@
 	up(&f->sem);
 	jffs3_complete_reservation(c);
 	ret = jffs3_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_DIRENT_SIZE(namelen));
-		
+
 	if (ret) {
 		/* Eep. */
 		DBG_WRITE(1, "jffs3_reserve_space() for dirent failed\n");
@@ -502,9 +510,9 @@
 	fd = jffs3_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);
 
 	jffs3_free_raw_dirent(rd);
-	
+
 	if (IS_ERR(fd)) {
-		/* dirent failed to write. Delete the inode normally 
+		/* dirent failed to write. Delete the inode normally
 		   as if it were the final unlink() */
 		jffs3_complete_reservation(c);
 		up(&dir_f->sem);
@@ -530,7 +538,7 @@
 	uint32_t alloclen, phys_ofs;
 	int ret;
 
-	if (1 /* alternative branch needs testing */ || 
+	if (1 /* alternative branch needs testing */ ||
 	    !jffs3_can_mark_obsolete(c)) {
 		/* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */
 
@@ -551,7 +559,7 @@
 		rd->nodetype = cpu_to_je16(JFFS3_NODETYPE_DIRENT);
 		rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
 		rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs3_unknown_node)-4));
-		
+
 		rd->pino = cpu_to_je32(dir_f->inocache->ino);
 		rd->version = cpu_to_je32(++dir_f->highest_version);
 		rd->ino = cpu_to_je32(0);
@@ -562,7 +570,7 @@
 		rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
 
 		fd = jffs3_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION);
-		
+
 		jffs3_free_raw_dirent(rd);
 
 		if (IS_ERR(fd)) {
@@ -581,7 +589,7 @@
 		down(&dir_f->sem);
 
 		while ((*prev) && (*prev)->nhash <= nhash) {
-			if ((*prev)->nhash == nhash && 
+			if ((*prev)->nhash == nhash &&
 			    !memcmp((*prev)->name, name, namelen) &&
 			    !(*prev)->name[namelen]) {
 				struct jffs3_full_dirent *this = *prev;
@@ -602,16 +610,16 @@
 	/* dead_f is NULL if this was a rename not a real unlink */
 	/* Also catch the !f->inocache case, where there was a dirent
 	   pointing to an inode which didn't exist. */
-	if (dead_f && dead_f->inocache) { 
+	if (dead_f && dead_f->inocache) {
 
 		down(&dead_f->sem);
 
 		while (dead_f->dents) {
 			/* There can be only deleted ones */
 			fd = dead_f->dents;
-			
+
 			dead_f->dents = fd->next;
-			
+
 			if (fd->ino) {
 				WARNING_MSG("Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
 				       dead_f->inocache->ino, fd->name, fd->ino);
@@ -650,7 +658,7 @@
 		jffs3_free_raw_dirent(rd);
 		return ret;
 	}
-	
+
 	down(&dir_f->sem);
 
 	/* Build a deletion node */
@@ -671,7 +679,7 @@
 	rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
 
 	fd = jffs3_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);
-	
+
 	jffs3_free_raw_dirent(rd);
 
 	if (IS_ERR(fd)) {





More information about the linux-mtd-cvs mailing list