This is the mail archive of the
ecos-patches@sources.redhat.com
mailing list for the eCos project.
JFFS2 - merge changes from main CVS
- From: Gary Thomas <gary at mlbassoc dot com>
- To: eCos patches <ecos-patches at sources dot redhat dot com>
- Date: 15 Jul 2003 14:47:48 -0600
- Subject: JFFS2 - merge changes from main CVS
- Organization: MLB Associates
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