This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

JFFS2 - merge changes from main CVS


Bring up to date with the latest Linux/CVS code

-- 
Gary Thomas <gary@mlbassoc.com>
MLB Associates
Only in /work2/ecos/packages/fs/jffs2/current/cdl: CVS
diff -ur /work2/ecos/packages/fs/jffs2/current/cdl/jffs2.cdl fs/jffs2/current/cdl/jffs2.cdl
--- /work2/ecos/packages/fs/jffs2/current/cdl/jffs2.cdl	2003-02-24 11:05:13.000000000 -0700
+++ fs/jffs2/current/cdl/jffs2.cdl	2003-07-15 14:42:50.000000000 -0600
@@ -4,6 +4,8 @@
 #
 #      JFFS2 Filesystem configuration data
 #
+#      $Id: jffs2.cdl,v 1.5 2003/07/15 20:42:32 gthomas Exp $
+#
 # ====================================================================
 #####ECOSGPLCOPYRIGHTBEGIN####
 ## -------------------------------------------
Only in /work2/ecos/packages/fs/jffs2/current: ChangeLog
Only in /work2/ecos/packages/fs/jffs2/current: CVS
Only in /work2/ecos/packages/fs/jffs2/current: doc
Only in /work2/ecos/packages/fs/jffs2/current/include: CVS
Only in /work2/ecos/packages/fs/jffs2/current/include/linux: CVS
diff -ur /work2/ecos/packages/fs/jffs2/current/include/linux/jffs2_fs_sb.h fs/jffs2/current/include/linux/jffs2_fs_sb.h
--- /work2/ecos/packages/fs/jffs2/current/include/linux/jffs2_fs_sb.h	2003-02-04 17:03:17.000000000 -0700
+++ fs/jffs2/current/include/linux/jffs2_fs_sb.h	2003-07-15 14:42:50.000000000 -0600
@@ -1,4 +1,4 @@
-/* $Id: jffs2_fs_sb.h,v 1.37 2003/01/17 16:04:44 dwmw2 Exp $ */
+/* $Id: jffs2_fs_sb.h,v 1.39 2003/06/30 14:36:47 dwmw2 Exp $ */
 
 #ifndef _JFFS2_FS_SB
 #define _JFFS2_FS_SB
@@ -84,6 +84,7 @@
 	   to an obsoleted node. I don't like this. Alternatives welcomed. */
 	struct semaphore erase_free_sem;
 
+#ifdef CONFIG_JFFS2_FS_NAND
 	/* Write-behind buffer for NAND flash */
 	unsigned char *wbuf;
 	uint32_t wbuf_ofs;
@@ -92,6 +93,13 @@
 	struct work_struct wbuf_task;		/* task for timed wbuf flush */
 	struct timer_list wbuf_timer;		/* timer for flushing wbuf */
 
+	/* Information about out-of-band area usage... */
+	struct nand_oobinfo *oobinfo;
+	uint32_t badblock_pos;
+	uint32_t fsdata_pos;
+	uint32_t fsdata_len;
+#endif
+
 	/* OS-private pointer for getting back to master superblock info */
 	void *os_priv;
 };
diff -ur /work2/ecos/packages/fs/jffs2/current/include/linux/jffs2.h fs/jffs2/current/include/linux/jffs2.h
--- /work2/ecos/packages/fs/jffs2/current/include/linux/jffs2.h	2003-02-04 17:03:17.000000000 -0700
+++ fs/jffs2/current/include/linux/jffs2.h	2003-07-15 14:42:50.000000000 -0600
@@ -8,7 +8,7 @@
  * For licensing information, see the file 'LICENCE' in the 
  * jffs2 directory.
  *
- * $Id: jffs2.h,v 1.29 2003/01/22 11:59:23 dwmw2 Exp $
+ * $Id: jffs2.h,v 1.30 2003/02/15 00:15:22 dwmw2 Exp $
  *
  */
 
@@ -24,7 +24,7 @@
 /* Values we may expect to find in the 'magic' field */
 #define JFFS2_OLD_MAGIC_BITMASK 0x1984
 #define JFFS2_MAGIC_BITMASK 0x1985
-#define KSAMTIB_CIGAM_2SFFJ 0x5981 /* For detecting wrong-endian fs */
+#define KSAMTIB_CIGAM_2SFFJ 0x8519 /* For detecting wrong-endian fs */
 #define JFFS2_EMPTY_BITMASK 0xffff
 #define JFFS2_DIRTY_BITMASK 0x0000
 
diff -ur /work2/ecos/packages/fs/jffs2/current/src/build.c fs/jffs2/current/src/build.c
--- /work2/ecos/packages/fs/jffs2/current/src/build.c	2003-02-04 14:43:16.000000000 -0700
+++ fs/jffs2/current/src/build.c	2003-07-15 14:42:49.000000000 -0600
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: build.c,v 1.44 2003/01/17 16:04:16 dwmw2 Exp $
+ * $Id: build.c,v 1.46 2003/04/29 17:12:26 gleixner Exp $
  *
  */
 
@@ -19,8 +19,30 @@
 int jffs2_build_inode_pass1(struct jffs2_sb_info *, struct jffs2_inode_cache *);
 int jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *, struct jffs2_inode_cache *);
 
+static inline struct jffs2_inode_cache *
+first_inode_chain(int *i, struct jffs2_sb_info *c)
+{
+	for (; *i < INOCACHE_HASHSIZE; (*i)++) {
+		if (c->inocache_list[*i])
+			return c->inocache_list[*i];
+	}
+	return NULL;
+}
+
+static inline struct jffs2_inode_cache *
+next_inode(int *i, struct jffs2_inode_cache *ic, struct jffs2_sb_info *c)
+{
+	/* More in this chain? */
+	if (ic->next)
+		return ic->next;
+	(*i)++;
+	return first_inode_chain(i, c);
+}
 
-#define for_each_inode(i, c, ic) for (i=0; i<INOCACHE_HASHSIZE; i++) for (ic=c->inocache_list[i]; ic; ic=ic->next) 
+#define for_each_inode(i, c, ic)			\
+	for (i = 0, ic = first_inode_chain(&i, (c));	\
+	     ic;					\
+	     ic = next_inode(&i, ic, (c)))
 
 /* Scan plan:
  - Scan physical nodes. Build map of inodes/dirents. Allocate inocaches as we go
diff -ur /work2/ecos/packages/fs/jffs2/current/src/compr_rtime.c fs/jffs2/current/src/compr_rtime.c
--- /work2/ecos/packages/fs/jffs2/current/src/compr_rtime.c	2003-02-04 14:43:16.000000000 -0700
+++ fs/jffs2/current/src/compr_rtime.c	2003-07-15 14:42:50.000000000 -0600
@@ -7,13 +7,13 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: compr_rtime.c,v 1.9 2002/05/20 14:56:37 dwmw2 Exp $
+ * $Id: compr_rtime.c,v 1.10 2003/05/11 10:47:13 dwmw2 Exp $
  *
  *
  * Very simple lz77-ish encoder.
  *
  * Theory of operation: Both encoder and decoder have a list of "last
- * occurances" for every possible source-value; after sending the
+ * occurrences" for every possible source-value; after sending the
  * first source-byte, the second byte indicated the "run" length of
  * matches
  *
@@ -30,7 +30,7 @@
 int jffs2_rtime_compress(unsigned char *data_in, unsigned char *cpage_out, 
 		   uint32_t *sourcelen, uint32_t *dstlen)
 {
-	int positions[256];
+	short positions[256];
 	int outpos = 0;
 	int pos=0;
 
@@ -70,7 +70,7 @@
 void jffs2_rtime_decompress(unsigned char *data_in, unsigned char *cpage_out,
 		      uint32_t srclen, uint32_t destlen)
 {
-	int positions[256];
+	short positions[256];
 	int outpos = 0;
 	int pos=0;
 	
diff -ur /work2/ecos/packages/fs/jffs2/current/src/compr_zlib.c fs/jffs2/current/src/compr_zlib.c
--- /work2/ecos/packages/fs/jffs2/current/src/compr_zlib.c	2003-02-04 14:43:16.000000000 -0700
+++ fs/jffs2/current/src/compr_zlib.c	2003-07-15 14:42:49.000000000 -0600
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: compr_zlib.c,v 1.22 2003/01/12 13:21:28 dwmw2 Exp $
+ * $Id: compr_zlib.c,v 1.23 2003/05/26 09:15:19 dwmw2 Exp $
  *
  */
 
@@ -17,7 +17,8 @@
 
 #include <linux/config.h>
 #include <linux/kernel.h>
-#include <linux/mtd/compatmac.h> /* for min() */
+#include <linux/vmalloc.h>
+#include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/zlib.h>
 #include <linux/zutil.h>
Only in /work2/ecos/packages/fs/jffs2/current/src: CVS
diff -ur /work2/ecos/packages/fs/jffs2/current/src/erase.c fs/jffs2/current/src/erase.c
--- /work2/ecos/packages/fs/jffs2/current/src/erase.c	2003-02-04 14:43:16.000000000 -0700
+++ fs/jffs2/current/src/erase.c	2003-07-15 14:42:50.000000000 -0600
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: erase.c,v 1.49 2003/01/21 18:11:28 dwmw2 Exp $
+ * $Id: erase.c,v 1.51 2003/05/11 22:47:36 dwmw2 Exp $
  *
  */
 
@@ -52,6 +52,8 @@
 		list_del(&jeb->list);
 		list_add(&jeb->list, &c->erase_pending_list);
 		c->erasing_size -= c->sector_size;
+		c->dirty_size += c->sector_size;
+		jeb->dirty_size = c->sector_size;
 		spin_unlock(&c->erase_completion_lock);
 		return;
 	}
@@ -85,6 +87,8 @@
 		list_del(&jeb->list);
 		list_add(&jeb->list, &c->erase_pending_list);
 		c->erasing_size -= c->sector_size;
+		c->dirty_size += c->sector_size;
+		jeb->dirty_size = c->sector_size;
 		spin_unlock(&c->erase_completion_lock);
 		return;
 	}
@@ -94,12 +98,6 @@
 	else
 		printk(KERN_WARNING "Erase at 0x%08x failed immediately: errno %d\n", jeb->offset, ret);
 
-	/* Note: This is almost identical to jffs2_erase_failed() except
-	   for the fact that we used spin_lock() not spin_lock(). If
-	   we could use spin_lock() from a BH, we could merge them.
-	   Or if we abandon the idea that MTD drivers may call the erase
-	   callback from a BH, I suppose :)
-	*/
 	jffs2_erase_failed(c, jeb);
 }
 
diff -ur /work2/ecos/packages/fs/jffs2/current/src/fs-ecos.c fs/jffs2/current/src/fs-ecos.c
--- /work2/ecos/packages/fs/jffs2/current/src/fs-ecos.c	2003-04-28 12:03:40.000000000 -0600
+++ fs/jffs2/current/src/fs-ecos.c	2003-07-15 14:42:50.000000000 -0600
@@ -8,7 +8,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: fs-ecos.c,v 1.8 2003/01/21 18:13:01 dwmw2 Exp $
+ * $Id: fs-ecos.c,v 1.9 2003/07/15 20:42:33 gthomas Exp $
  *
  */
 
diff -ur /work2/ecos/packages/fs/jffs2/current/src/gc.c fs/jffs2/current/src/gc.c
--- /work2/ecos/packages/fs/jffs2/current/src/gc.c	2003-02-04 14:43:16.000000000 -0700
+++ fs/jffs2/current/src/gc.c	2003-07-15 14:42:50.000000000 -0600
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: gc.c,v 1.100 2003/01/22 14:43:51 dwmw2 Exp $
+ * $Id: gc.c,v 1.103 2003/05/22 18:01:02 dwmw2 Exp $
  *
  */
 
@@ -122,8 +122,6 @@
 		return -EINTR;
 
 	for (;;) {
-		struct jffs2_inode_cache *ic;
-
 		spin_lock(&c->erase_completion_lock);
 		if (!c->unchecked_size)
 			break;
@@ -191,8 +189,10 @@
 		D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() triggering inode scan of ino#%d\n", ic->ino));
 
 		ret = jffs2_do_crccheck_inode(c, ic);
-		if (!ret)
-			jffs2_set_inocache_state(c, ic, INO_STATE_CHECKEDABSENT);
+		if (ret)
+			printk(KERN_WARNING "Returned error for crccheck of ino #%u. Expect badness...\n", ic->ino);
+
+		jffs2_set_inocache_state(c, ic, INO_STATE_CHECKEDABSENT);
 		up(&c->alloc_sem);
 		return ret;
 	}
@@ -624,7 +624,7 @@
 {
 	struct jffs2_full_dnode *new_fn;
 	struct jffs2_raw_inode ri;
-	unsigned short dev;
+	jint16_t dev;
 	char *mdata = NULL, mdatalen = 0;
 	uint32_t alloclen, phys_ofs;
 	int ret;
@@ -633,8 +633,8 @@
 	    S_ISCHR(JFFS2_F_I_MODE(f)) ) {
 		/* For these, we don't actually need to read the old node */
 		/* FIXME: for minor or major > 255. */
-		dev =  ((JFFS2_F_I_RDEV_MAJ(f) << 8) | 
-			JFFS2_F_I_RDEV_MIN(f));
+		dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) | 
+			JFFS2_F_I_RDEV_MIN(f)));
 		mdata = (char *)&dev;
 		mdatalen = sizeof(dev);
 		D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bytes of kdev_t\n", mdatalen));
diff -ur /work2/ecos/packages/fs/jffs2/current/src/nodelist.c fs/jffs2/current/src/nodelist.c
--- /work2/ecos/packages/fs/jffs2/current/src/nodelist.c	2003-02-04 14:43:16.000000000 -0700
+++ fs/jffs2/current/src/nodelist.c	2003-07-15 14:42:50.000000000 -0600
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: nodelist.c,v 1.75 2003/01/21 18:11:28 dwmw2 Exp $
+ * $Id: nodelist.c,v 1.79 2003/04/08 08:20:01 dwmw2 Exp $
  *
  */
 
@@ -159,6 +159,14 @@
 				err = -EIO;
 				goto free_out;
 			}
+			/* sanity check */
+			if (PAD((node.d.nsize + sizeof (node.d))) != PAD(je32_to_cpu (node.d.totlen))) {
+				printk(KERN_NOTICE "jffs2_get_inode_nodes(): Illegal nsize in node at 0x%08x: nsize 0x%02x, totlen %04x\n",
+				       ref_offset(ref), node.d.nsize, je32_to_cpu(node.d.totlen));
+				jffs2_mark_node_obsolete(c, ref);
+				spin_lock(&c->erase_completion_lock);
+				continue;
+			}
 			if (je32_to_cpu(node.d.version) > *highest_version)
 				*highest_version = je32_to_cpu(node.d.version);
 			if (ref_obsolete(ref)) {
@@ -167,6 +175,7 @@
 				       ref_offset(ref));
 				BUG();
 			}
+			
 			fd = jffs2_alloc_full_dirent(node.d.nsize+1);
 			if (!fd) {
 				err = -ENOMEM;
@@ -248,6 +257,18 @@
 					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)) != PAD(je32_to_cpu(node.i.totlen))) {
+					printk(KERN_NOTICE "jffs2_get_inode_nodes(): 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.csize), je32_to_cpu(node.i.dsize));
+					jffs2_mark_node_obsolete(c, ref);
+					spin_lock(&c->erase_completion_lock);
+					continue;
+				}
 
 				if (node.i.compr != JFFS2_COMPR_ZERO && je32_to_cpu(node.i.csize)) {
 					unsigned char *buf=NULL;
@@ -429,7 +450,7 @@
    Rather than introducing special case get_ino_cache functions or 
    callbacks, we just let the caller do the locking itself. */
    
-struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, int ino)
+struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
 {
 	struct jffs2_inode_cache *ret;
 
diff -ur /work2/ecos/packages/fs/jffs2/current/src/nodelist.h fs/jffs2/current/src/nodelist.h
--- /work2/ecos/packages/fs/jffs2/current/src/nodelist.h	2003-02-04 14:43:16.000000000 -0700
+++ fs/jffs2/current/src/nodelist.h	2003-07-15 14:42:50.000000000 -0600
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: nodelist.h,v 1.92 2003/01/22 14:43:29 dwmw2 Exp $
+ * $Id: nodelist.h,v 1.94 2003/07/03 10:35:45 dwmw2 Exp $
  *
  */
 
@@ -29,7 +29,7 @@
 #endif
 
 #ifndef CONFIG_JFFS2_FS_DEBUG
-#define CONFIG_JFFS2_FS_DEBUG 2
+#define CONFIG_JFFS2_FS_DEBUG 1
 #endif
 
 #if CONFIG_JFFS2_FS_DEBUG > 0
@@ -292,7 +292,7 @@
 			  uint32_t *highest_version, uint32_t *latest_mctime,
 			  uint32_t *mctime_ver);
 void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state);
-struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, int ino);
+struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino);
 void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new);
 void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old);
 void jffs2_free_ino_caches(struct jffs2_sb_info *c);
diff -ur /work2/ecos/packages/fs/jffs2/current/src/nodemgmt.c fs/jffs2/current/src/nodemgmt.c
--- /work2/ecos/packages/fs/jffs2/current/src/nodemgmt.c	2003-02-04 14:43:16.000000000 -0700
+++ fs/jffs2/current/src/nodemgmt.c	2003-07-15 14:42:50.000000000 -0600
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: nodemgmt.c,v 1.92 2003/01/22 14:40:26 dwmw2 Exp $
+ * $Id: nodemgmt.c,v 1.95 2003/06/30 10:58:57 dwmw2 Exp $
  *
  */
 
@@ -57,16 +57,47 @@
 
 	spin_lock(&c->erase_completion_lock);
 
-	/* this needs a little more thought */
+	/* this needs a little more thought (true <tglx> :)) */
 	while(ret == -EAGAIN) {
 		while(c->nr_free_blocks + c->nr_erasing_blocks < blocksneeded) {
 			int ret;
+			uint32_t dirty, avail;
 
 			up(&c->alloc_sem);
 			
-			if (c->dirty_size + c->unchecked_size < c->sector_size) {
+			/* calculate real dirty size
+			 * dirty_size contains blocks on erase_pending_list
+			 * those blocks are counted in c->nr_erasing_blocks.
+			 * If one block is actually erased, it is not longer counted as dirty_space
+			 * but it is counted in c->nr_erasing_blocks, so we add it and subtract it
+			 * with c->nr_erasing_blocks * c->sector_size again.
+			 * Blocks on erasable_list are counted as dirty_size, but not in c->nr_erasing_blocks
+			 * This helps us to force gc and pick eventually a clean block to spread the load.
+			 * We add unchecked_size here, as we hopefully will find some space to use.
+			 * This will affect the sum only once, as gc first finishes checking
+			 * of nodes.
+			 */
+			dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size + c->unchecked_size;
+			if (dirty < c->sector_size) {
 				D1(printk(KERN_DEBUG "dirty size 0x%08x + unchecked_size 0x%08x < sector size 0x%08x, returning -ENOSPC\n",
-					  c->dirty_size, c->unchecked_size, c->sector_size));
+					  dirty, c->unchecked_size, c->sector_size));
+				spin_unlock(&c->erase_completion_lock);
+				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 
+			 * blocksneeded * sector_size.
+			 * This blocks endless gc looping on a filesystem, which is nearly full, even if
+			 * the check above passes.
+			 */
+			avail = c->free_size + c->dirty_size + c->erasing_size + c->unchecked_size;
+			if ( (avail / c->sector_size) <= blocksneeded) {
+				D1(printk(KERN_DEBUG "max. available size 0x%08x  < blocksneeded * sector_size 0x%08x, returning -ENOSPC\n",
+					  avail, blocksneeded * c->sector_size));
 				spin_unlock(&c->erase_completion_lock);
 				return -ENOSPC;
 			}
@@ -127,7 +158,7 @@
 	if (jeb && minsize > jeb->free_size) {
 		/* Skip the end of this block and file it as having some dirty space */
 		/* If there's a pending write to it, flush now */
-		if (c->wbuf_len) {
+		if (jffs2_wbuf_dirty(c)) {
 			spin_unlock(&c->erase_completion_lock);
 			D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n"));			    
 			jffs2_flush_wbuf(c, 1);
@@ -313,7 +344,7 @@
 		/* If it lives on the dirty_list, jffs2_reserve_space will put it there */
 		D1(printk(KERN_DEBUG "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));
-		if (c->wbuf_len) {
+		if (jffs2_wbuf_dirty(c)) {
 			/* Flush the last write in the block if it's outstanding */
 			spin_unlock(&c->erase_completion_lock);
 			jffs2_flush_wbuf(c, 1);
@@ -344,7 +375,7 @@
 	struct jffs2_eraseblock *jeb;
 	int blocknr;
 	struct jffs2_unknown_node n;
-	int ret;
+	int ret, addedsize;
 	size_t retlen;
 
 	if(!ref) {
@@ -384,14 +415,17 @@
 		c->used_size -= ref->totlen;
 	}
 
+	// Take care, that wasted size is taken into concern
 	if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref->totlen)) && jeb != c->nextblock) {
 		D1(printk("Dirtying\n"));
-		jeb->dirty_size += ref->totlen + jeb->wasted_size;
-		c->dirty_size += ref->totlen + jeb->wasted_size;
+		addedsize = ref->totlen + jeb->wasted_size;
+		jeb->dirty_size += addedsize;
+		c->dirty_size += addedsize;
 		c->wasted_size -= jeb->wasted_size;
 		jeb->wasted_size = 0;
 	} else {
 		D1(printk("Wasting\n"));
+		addedsize = 0;
 		jeb->wasted_size += ref->totlen;
 		c->wasted_size += ref->totlen;	
 	}
@@ -421,7 +455,7 @@
 			D1(printk(KERN_DEBUG "Eraseblock at 0x%08x completely dirtied. Removing from (dirty?) list...\n", jeb->offset));
 			list_del(&jeb->list);
 		}
-		if (c->wbuf_len) {
+		if (jffs2_wbuf_dirty(c)) {
 			D1(printk(KERN_DEBUG "...and adding to erasable_pending_wbuf_list\n"));
 			list_add_tail(&jeb->list, &c->erasable_pending_wbuf_list);
 #if 0 /* This check was added to allow us to find places where we added nodes to the lists
@@ -466,7 +500,7 @@
 		D1(printk(KERN_DEBUG "Done OK\n"));
 	} else if (jeb == c->gcblock) {
 		D2(printk(KERN_DEBUG "Not moving gcblock 0x%08x to dirty_list\n", jeb->offset));
-	} else if (ISDIRTY(jeb->dirty_size) && !ISDIRTY(jeb->dirty_size - ref->totlen)) {
+	} else if (ISDIRTY(jeb->dirty_size) && !ISDIRTY(jeb->dirty_size - addedsize)) {
 		D1(printk(KERN_DEBUG "Eraseblock at 0x%08x is freshly dirtied. Removing from clean list...\n", jeb->offset));
 		list_del(&jeb->list);
 		D1(printk(KERN_DEBUG "...and adding to dirty_list\n"));
diff -ur /work2/ecos/packages/fs/jffs2/current/src/read.c fs/jffs2/current/src/read.c
--- /work2/ecos/packages/fs/jffs2/current/src/read.c	2003-02-04 14:43:16.000000000 -0700
+++ fs/jffs2/current/src/read.c	2003-07-15 14:42:50.000000000 -0600
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: read.c,v 1.31 2003/01/14 14:06:22 dwmw2 Exp $
+ * $Id: read.c,v 1.32 2003/07/15 10:11:37 dwmw2 Exp $
  *
  */
 
@@ -165,7 +165,7 @@
 	/* Now we're pointing at the first frag which overlaps our page */
 	while(offset < end) {
 		D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end));
-		if (!frag || frag->ofs > offset) {
+		if (unlikely(!frag || frag->ofs > offset)) {
 			uint32_t holesize = end - offset;
 			if (frag) {
 				D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset));
@@ -177,13 +177,7 @@
 			buf += holesize;
 			offset += holesize;
 			continue;
-		} else if (frag->ofs < offset && (offset & (PAGE_CACHE_SIZE-1)) != 0) {
-			D1(printk(KERN_NOTICE "Eep. Overlap in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n",
-				  f->inocache->ino, frag->ofs, offset));
-			D1(jffs2_print_frag_list(f));
-			memset(buf, 0, end - offset);
-			return -EIO;
-		} else if (!frag->node) {
+		} else if (unlikely(!frag->node)) {
 			uint32_t holeend = min(end, frag->ofs + frag->size);
 			D1(printk(KERN_DEBUG "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", offset, holeend, frag->ofs, frag->ofs + frag->size));
 			memset(buf, 0, holeend - offset);
diff -ur /work2/ecos/packages/fs/jffs2/current/src/readinode.c fs/jffs2/current/src/readinode.c
--- /work2/ecos/packages/fs/jffs2/current/src/readinode.c	2003-02-04 14:43:16.000000000 -0700
+++ fs/jffs2/current/src/readinode.c	2003-07-15 14:42:50.000000000 -0600
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: readinode.c,v 1.103 2003/01/22 14:43:29 dwmw2 Exp $
+ * $Id: readinode.c,v 1.106 2003/05/14 06:53:26 dwmw2 Exp $
  *
  */
 
@@ -169,8 +169,10 @@
 		if (lastend < newfrag->node->ofs) {
 			/* ... and we need to put a hole in before the new node */
 			struct jffs2_node_frag *holefrag = jffs2_alloc_node_frag();
-			if (!holefrag)
+			if (!holefrag) {
+				jffs2_free_node_frag(newfrag);
 				return -ENOMEM;
+			}
 			holefrag->ofs = lastend;
 			holefrag->size = newfrag->node->ofs - lastend;
 			holefrag->node = NULL;
@@ -408,6 +410,7 @@
 {
 	struct jffs2_raw_inode n;
 	struct jffs2_inode_info *f = kmalloc(sizeof(*f), GFP_KERNEL);
+	int ret;
 
 	if (!f)
 		return -ENOMEM;
@@ -416,7 +419,13 @@
 	init_MUTEX_LOCKED(&f->sem);
 	f->inocache = ic;
 
-	return jffs2_do_read_inode_internal(c, f, &n);
+	ret = jffs2_do_read_inode_internal(c, f, &n);
+	if (!ret) {
+		up(&f->sem);
+		jffs2_do_clear_inode(c, f);
+	}
+	kfree (f);
+	return ret;
 }
 
 static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, 
@@ -450,13 +459,21 @@
 
 		fn = tn->fn;
 
-		if (f->metadata && tn->version > mdata_ver) {
-			D1(printk(KERN_DEBUG "Obsoleting old metadata at 0x%08x\n", ref_offset(f->metadata->raw)));
-			jffs2_mark_node_obsolete(c, f->metadata->raw);
-			jffs2_free_full_dnode(f->metadata);
-			f->metadata = NULL;
-			
-			mdata_ver = 0;
+		if (f->metadata) {
+			if (tn->version > mdata_ver) {
+				D1(printk(KERN_DEBUG "Obsoleting old metadata at 0x%08x\n", ref_offset(f->metadata->raw)));
+				jffs2_mark_node_obsolete(c, f->metadata->raw);
+				jffs2_free_full_dnode(f->metadata);
+				f->metadata = NULL;
+				
+				mdata_ver = 0;
+			} else {
+				D1(printk(KERN_DEBUG "Er. New metadata at 0x%08x with ver %d is actually older than previous %d\n",
+				       ref_offset(f->metadata->raw), tn->version, mdata_ver));
+				jffs2_mark_node_obsolete(c, fn->raw);
+				jffs2_free_full_dnode(fn);
+				goto next_tn;
+			}
 		}
 
 		if (fn->size) {
@@ -467,6 +484,7 @@
 			f->metadata = fn;
 			mdata_ver = tn->version;
 		}
+	next_tn:
 		tn_list = tn->next;
 		jffs2_free_tmp_dnode_info(tn);
 	}
diff -ur /work2/ecos/packages/fs/jffs2/current/src/scan.c fs/jffs2/current/src/scan.c
--- /work2/ecos/packages/fs/jffs2/current/src/scan.c	2003-02-04 14:43:16.000000000 -0700
+++ fs/jffs2/current/src/scan.c	2003-07-15 14:42:50.000000000 -0600
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: scan.c,v 1.98 2003/01/22 16:33:39 dwmw2 Exp $
+ * $Id: scan.c,v 1.101 2003/06/30 10:58:57 dwmw2 Exp $
  *
  */
 #include <linux/kernel.h>
@@ -65,6 +65,16 @@
 #define BLK_STATE_ALLDIRTY	4
 #define BLK_STATE_BADBLOCK	5
 
+static inline int min_free(struct jffs2_sb_info *c)
+{
+	uint32_t min = 2 * sizeof(struct jffs2_raw_inode);
+#ifdef CONFIG_JFFS2_FS_NAND
+	if (!jffs2_can_mark_obsolete(c) && min < c->wbuf_pagesize)
+		return c->wbuf_pagesize;
+#endif
+	return min;
+
+}
 int jffs2_scan_medium(struct jffs2_sb_info *c)
 {
 	int i, ret;
@@ -151,8 +161,7 @@
                            Later when we do snapshots, this must be the most recent block,
                            not the one with most free space.
                         */
-                        if (jeb->free_size > 2*sizeof(struct jffs2_raw_inode) && 
-			    (jffs2_can_mark_obsolete(c) || jeb->free_size > c->wbuf_pagesize) &&
+                        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) {
@@ -210,7 +219,7 @@
 		c->dirty_size -= c->nextblock->dirty_size;
 		c->nextblock->dirty_size = 0;
 	}
-
+#ifdef CONFIG_JFFS2_FS_NAND
 	if (!jffs2_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 
 		   contains data, and the end of the data isn't page-aligned,
@@ -226,6 +235,7 @@
 		c->nextblock->free_size -= skip;
 		c->free_size -= skip;
 	}
+#endif
 	if (c->nr_erasing_blocks) {
 		if ( !c->used_size && ((empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) {
 			printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
@@ -354,7 +364,7 @@
 
 		if (ofs & 3) {
 			printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs);
-			ofs = (ofs+3)&~3;
+			ofs = PAD(ofs);
 			continue;
 		}
 		if (ofs == prevofs) {
@@ -410,8 +420,8 @@
 			/* Ran off end. */
 			D1(printk(KERN_DEBUG "Empty flash ends normally at 0x%08x\n", ofs));
 
-			if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && 
-			    !jeb->first_node->next_in_ino && !jeb->dirty_size)
+			if (buf_ofs == jeb->offset &&  jeb->used_size == PAD(c->cleanmarker_size) && 
+			    c->cleanmarker_size && !jeb->first_node->next_in_ino && !jeb->dirty_size)
 				return BLK_STATE_CLEANMARKER;
 			wasempty = 1;
 			continue;
@@ -430,7 +440,7 @@
 			continue;
 		}
 		if (je16_to_cpu(node->magic) == JFFS2_DIRTY_BITMASK) {
-			D1(printk(KERN_DEBUG "Empty bitmask at 0x%08x\n", ofs));
+			D1(printk(KERN_DEBUG "Dirty bitmask at 0x%08x\n", ofs));
 			DIRTY_SPACE(4);
 			ofs += 4;
 			continue;
Only in /work2/ecos/packages/fs/jffs2/current: support
Only in /work2/ecos/packages/fs/jffs2/current/tests: CVS

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]