aboutsummaryrefslogtreecommitdiff
path: root/fs/jffs2
diff options
context:
space:
mode:
authorArtem B. Bityutskiy <dedekind@infradead.org>2005-09-22 12:25:00 +0100
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-11-06 22:20:33 +0100
commit733802d974e5af42acb7cd61b16c0ce6dd03b7ed (patch)
tree56f77d78d9a2df474bb1686f5d060ee1e84a4d68 /fs/jffs2
parentb523b3bac3a745fefd6f604082f2ffa09b808e5e (diff)
[JFFS2] Debug code simplification, update TODO
Simplify the debugging code further. Update the TODO list Signed-off-by: Artem B. Bityutskiy <dedekind@infradead.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/jffs2')
-rw-r--r--fs/jffs2/TODO38
-rw-r--r--fs/jffs2/build.c112
-rw-r--r--fs/jffs2/debug.c3
-rw-r--r--fs/jffs2/debug.h50
-rw-r--r--fs/jffs2/erase.c2
-rw-r--r--fs/jffs2/malloc.c34
-rw-r--r--fs/jffs2/nodelist.c107
-rw-r--r--fs/jffs2/nodemgmt.c6
-rw-r--r--fs/jffs2/os-linux.h6
-rw-r--r--fs/jffs2/readinode.c32
-rw-r--r--fs/jffs2/scan.c48
-rw-r--r--fs/jffs2/summary.c53
-rw-r--r--fs/jffs2/wbuf.c5
13 files changed, 232 insertions, 264 deletions
diff --git a/fs/jffs2/TODO b/fs/jffs2/TODO
index 2bff82fd221..d0e23b26fa5 100644
--- a/fs/jffs2/TODO
+++ b/fs/jffs2/TODO
@@ -1,5 +1,11 @@
-$Id: TODO,v 1.10 2002/09/09 16:31:21 dwmw2 Exp $
+$Id: TODO,v 1.18 2005/09/22 11:24:56 dedekind Exp $
+ - support asynchronous operation -- add a per-fs 'reserved_space' count,
+ let each outstanding write reserve the _maximum_ amount of physical
+ space it could take. Let GC flush the outstanding writes because the
+ reservations will necessarily be pessimistic. With this we could even
+ do shared writable mmap, if we can have a fs hook for do_wp_page() to
+ make the reservation.
- disable compression in commit_write()?
- fine-tune the allocation / GC thresholds
- chattr support - turning on/off and tuning compression per-inode
@@ -11,26 +17,15 @@ $Id: TODO,v 1.10 2002/09/09 16:31:21 dwmw2 Exp $
- test, test, test
- NAND flash support:
- - flush_wbuf using GC to fill it, don't just pad.
- - Deal with write errors. Data don't get lost - we just have to write
- the affected node(s) out again somewhere else.
- - make fsync flush only if actually required
- - make sys_sync() work.
- - reboot notifier
- - timed flush of old wbuf
- - fix magical second arg of jffs2_flush_wbuf(). Split into two or more functions instead.
-
+ - almost done :)
+ - use bad block check instead of the hardwired byte check
- Optimisations:
- - Stop GC from decompressing and immediately recompressing nodes which could
- just be copied intact. (We now keep track of REF_PRISTINE flag. Easy now.)
- - Furthermore, in the case where it could be copied intact we don't even need
- to call iget() for it -- if we use (raw_node_raw->flash_offset & 2) as a flag
- to show a node can be copied intact and it's _not_ in icache, we could just do
- it, fix up the next_in_ino list and move on. We would need a way to find out
- _whether_ it's in icache though -- if it's in icache we also need to do the
- fragment lists, etc. P'raps a flag or pointer in the jffs2_inode_cache could
- help. (We have half of this now.)
+ - Split writes so they go to two separate blocks rather than just c->nextblock.
+ By writing _new_ nodes to one block, and garbage-collected REF_PRISTINE
+ nodes to a different one, we can separate clean nodes from those which
+ are likely to become dirty, and end up with blocks which are each far
+ closer to 100% or 0% clean, hence speeding up later GC progress dramatically.
- Stop keeping name in-core with struct jffs2_full_dirent. If we keep the hash in
the full dirent, we only need to go to the flash in lookup() when we think we've
got a match, and in readdir().
@@ -38,3 +33,8 @@ $Id: TODO,v 1.10 2002/09/09 16:31:21 dwmw2 Exp $
- Remove totlen from jffs2_raw_node_ref? Need to have totlen passed into
jffs2_mark_node_obsolete(). Can all callers work it out?
- Remove size from jffs2_raw_node_frag.
+
+dedekind:
+1. __jffs2_flush_wbuf() has a strange 'pad' parameter. Eliminate.
+2. get_sb()->build_fs()->scan() path... Why get_sb() removes scan()'s crap in
+ case of failure? scan() does not clean everything. Fix.
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
index f2cf562ebd2..ac393b3d6ea 100644
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: build.c,v 1.79 2005/09/07 11:21:57 havasi Exp $
+ * $Id: build.c,v 1.83 2005/09/21 15:52:33 dedekind Exp $
*
*/
@@ -18,7 +18,8 @@
#include <linux/mtd/mtd.h>
#include "nodelist.h"
-static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *, struct jffs2_inode_cache *, struct jffs2_full_dirent **);
+static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *,
+ struct jffs2_inode_cache *, struct jffs2_full_dirent **);
static inline struct jffs2_inode_cache *
first_inode_chain(int *i, struct jffs2_sb_info *c)
@@ -46,11 +47,12 @@ next_inode(int *i, struct jffs2_inode_cache *ic, struct jffs2_sb_info *c)
ic = next_inode(&i, ic, (c)))
-static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
+static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
+ struct jffs2_inode_cache *ic)
{
struct jffs2_full_dirent *fd;
- D1(printk(KERN_DEBUG "jffs2_build_inode building directory inode #%u\n", ic->ino));
+ dbg_fsbuild("building directory inode #%u\n", ic->ino);
/* For each child, increase nlink */
for(fd = ic->scan_dents; fd; fd = fd->next) {
@@ -58,26 +60,23 @@ static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c, struct jffs2
if (!fd->ino)
continue;
- /* XXX: Can get high latency here with huge directories */
+ /* we can get high latency here with huge directories */
child_ic = jffs2_get_ino_cache(c, fd->ino);
if (!child_ic) {
- printk(KERN_NOTICE "Eep. Child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n",
+ dbg_fsbuild("child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n",
fd->name, fd->ino, ic->ino);
jffs2_mark_node_obsolete(c, fd->raw);
continue;
}
if (child_ic->nlink++ && fd->type == DT_DIR) {
- printk(KERN_NOTICE "Child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", fd->name, fd->ino, ic->ino);
- if (fd->ino == 1 && ic->ino == 1) {
- printk(KERN_NOTICE "This is mostly harmless, and probably caused by creating a JFFS2 image\n");
- printk(KERN_NOTICE "using a buggy version of mkfs.jffs2. Use at least v1.17.\n");
- }
- /* What do we do about it? */
+ JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n",
+ fd->name, fd->ino, ic->ino);
+ /* TODO: What do we do about it? */
}
- D1(printk(KERN_DEBUG "Increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino));
- /* Can't free them. We might need them in pass 2 */
+ dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino);
+ /* Can't free scan_dents so far. We might need them in pass 2 */
}
}
@@ -94,6 +93,8 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
struct jffs2_full_dirent *fd;
struct jffs2_full_dirent *dead_fds = NULL;
+ dbg_fsbuild("build FS data structures\n");
+
/* First, scan the medium and build all the inode caches with
lists of physical nodes */
@@ -103,33 +104,29 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
if (ret)
goto exit;
- D1(printk(KERN_DEBUG "Scanned flash completely\n"));
+ dbg_fsbuild("scanned flash completely\n");
jffs2_dbg_dump_block_lists_nolock(c);
+ dbg_fsbuild("pass 1 starting\n");
c->flags |= JFFS2_SB_FLAG_BUILDING;
/* Now scan the directory tree, increasing nlink according to every dirent found. */
for_each_inode(i, c, ic) {
- D1(printk(KERN_DEBUG "Pass 1: ino #%u\n", ic->ino));
-
- D1(BUG_ON(ic->ino > c->highest_ino));
-
if (ic->scan_dents) {
jffs2_build_inode_pass1(c, ic);
cond_resched();
}
}
- D1(printk(KERN_DEBUG "Pass 1 complete\n"));
+ dbg_fsbuild("pass 1 complete\n");
/* Next, scan for inodes with nlink == 0 and remove them. If
they were directories, then decrement the nlink of their
children too, and repeat the scan. As that's going to be
a fairly uncommon occurrence, it's not so evil to do it this
way. Recursion bad. */
- D1(printk(KERN_DEBUG "Pass 2 starting\n"));
+ dbg_fsbuild("pass 2 starting\n");
for_each_inode(i, c, ic) {
- D1(printk(KERN_DEBUG "Pass 2: ino #%u, nlink %d, ic %p, nodes %p\n", ic->ino, ic->nlink, ic, ic->nodes));
if (ic->nlink)
continue;
@@ -137,26 +134,24 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
cond_resched();
}
- D1(printk(KERN_DEBUG "Pass 2a starting\n"));
+ dbg_fsbuild("pass 2a starting\n");
while (dead_fds) {
fd = dead_fds;
dead_fds = fd->next;
ic = jffs2_get_ino_cache(c, fd->ino);
- D1(printk(KERN_DEBUG "Removing dead_fd ino #%u (\"%s\"), ic at %p\n", fd->ino, fd->name, ic));
if (ic)
jffs2_build_remove_unlinked_inode(c, ic, &dead_fds);
jffs2_free_full_dirent(fd);
}
- D1(printk(KERN_DEBUG "Pass 2 complete\n"));
+ dbg_fsbuild("pass 2a complete\n");
+ dbg_fsbuild("freeing temporary data structures\n");
/* Finally, we can scan again and free the dirent structs */
for_each_inode(i, c, ic) {
- D1(printk(KERN_DEBUG "Pass 3: ino #%u, ic %p, nodes %p\n", ic->ino, ic, ic->nodes));
-
while(ic->scan_dents) {
fd = ic->scan_dents;
ic->scan_dents = fd->next;
@@ -167,8 +162,7 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
}
c->flags &= ~JFFS2_SB_FLAG_BUILDING;
- D1(printk(KERN_DEBUG "Pass 3 complete\n"));
- jffs2_dbg_dump_block_lists_nolock(c);
+ dbg_fsbuild("FS build complete\n");
/* Rotate the lists by some number to ensure wear levelling */
jffs2_rotate_lists(c);
@@ -189,24 +183,26 @@ exit:
return ret;
}
-static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, struct jffs2_full_dirent **dead_fds)
+static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c,
+ struct jffs2_inode_cache *ic,
+ struct jffs2_full_dirent **dead_fds)
{
struct jffs2_raw_node_ref *raw;
struct jffs2_full_dirent *fd;
- D1(printk(KERN_DEBUG "JFFS2: Removing ino #%u with nlink == zero.\n", ic->ino));
+ dbg_fsbuild("removing ino #%u with nlink == zero.\n", ic->ino);
raw = ic->nodes;
while (raw != (void *)ic) {
struct jffs2_raw_node_ref *next = raw->next_in_ino;
- D1(printk(KERN_DEBUG "obsoleting node at 0x%08x\n", ref_offset(raw)));
+ dbg_fsbuild("obsoleting node at 0x%08x\n", ref_offset(raw));
jffs2_mark_node_obsolete(c, raw);
raw = next;
}
if (ic->scan_dents) {
int whinged = 0;
- D1(printk(KERN_DEBUG "Inode #%u was a directory which may have children...\n", ic->ino));
+ dbg_fsbuild("inode #%u was a directory which may have children...\n", ic->ino);
while(ic->scan_dents) {
struct jffs2_inode_cache *child_ic;
@@ -216,21 +212,19 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jf
if (!fd->ino) {
/* It's a deletion dirent. Ignore it */
- D1(printk(KERN_DEBUG "Child \"%s\" is a deletion dirent, skipping...\n", fd->name));
+ dbg_fsbuild("child \"%s\" is a deletion dirent, skipping...\n", fd->name);
jffs2_free_full_dirent(fd);
continue;
}
- if (!whinged) {
+ if (!whinged)
whinged = 1;
- printk(KERN_NOTICE "Inode #%u was a directory with children - removing those too...\n", ic->ino);
- }
- D1(printk(KERN_DEBUG "Removing child \"%s\", ino #%u\n",
- fd->name, fd->ino));
+ dbg_fsbuild("removing child \"%s\", ino #%u\n", fd->name, fd->ino);
child_ic = jffs2_get_ino_cache(c, fd->ino);
if (!child_ic) {
- printk(KERN_NOTICE "Cannot remove child \"%s\", ino #%u, because it doesn't exist\n", fd->name, fd->ino);
+ dbg_fsbuild("cannot remove child \"%s\", ino #%u, because it doesn't exist\n",
+ fd->name, fd->ino);
jffs2_free_full_dirent(fd);
continue;
}
@@ -241,13 +235,13 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jf
child_ic->nlink--;
if (!child_ic->nlink) {
- D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got zero nlink. Adding to dead_fds list.\n",
- fd->ino, fd->name));
+ dbg_fsbuild("inode #%u (\"%s\") has now got zero nlink, adding to dead_fds list.\n",
+ fd->ino, fd->name);
fd->next = *dead_fds;
*dead_fds = fd;
} else {
- D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got nlink %d. Ignoring.\n",
- fd->ino, fd->name, child_ic->nlink));
+ dbg_fsbuild("inode #%u (\"%s\") has now got nlink %d. Ignoring.\n",
+ fd->ino, fd->name, child_ic->nlink);
jffs2_free_full_dirent(fd);
}
}
@@ -295,20 +289,20 @@ static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
trying to GC to make more space. It'll be a fruitless task */
c->nospc_dirty_size = c->sector_size + (c->flash_size / 100);
- D1(printk(KERN_DEBUG "JFFS2 trigger levels (size %d KiB, block size %d KiB, %d blocks)\n",
- c->flash_size / 1024, c->sector_size / 1024, c->nr_blocks));
- D1(printk(KERN_DEBUG "Blocks required to allow deletion: %d (%d KiB)\n",
- c->resv_blocks_deletion, c->resv_blocks_deletion*c->sector_size/1024));
- D1(printk(KERN_DEBUG "Blocks required to allow writes: %d (%d KiB)\n",
- c->resv_blocks_write, c->resv_blocks_write*c->sector_size/1024));
- D1(printk(KERN_DEBUG "Blocks required to quiesce GC thread: %d (%d KiB)\n",
- c->resv_blocks_gctrigger, c->resv_blocks_gctrigger*c->sector_size/1024));
- D1(printk(KERN_DEBUG "Blocks required to allow GC merges: %d (%d KiB)\n",
- c->resv_blocks_gcmerge, c->resv_blocks_gcmerge*c->sector_size/1024));
- D1(printk(KERN_DEBUG "Blocks required to GC bad blocks: %d (%d KiB)\n",
- c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024));
- D1(printk(KERN_DEBUG "Amount of dirty space required to GC: %d bytes\n",
- c->nospc_dirty_size));
+ dbg_fsbuild("JFFS2 trigger levels (size %d KiB, block size %d KiB, %d blocks)\n",
+ c->flash_size / 1024, c->sector_size / 1024, c->nr_blocks);
+ dbg_fsbuild("Blocks required to allow deletion: %d (%d KiB)\n",
+ c->resv_blocks_deletion, c->resv_blocks_deletion*c->sector_size/1024);
+ dbg_fsbuild("Blocks required to allow writes: %d (%d KiB)\n",
+ c->resv_blocks_write, c->resv_blocks_write*c->sector_size/1024);
+ dbg_fsbuild("Blocks required to quiesce GC thread: %d (%d KiB)\n",
+ c->resv_blocks_gctrigger, c->resv_blocks_gctrigger*c->sector_size/1024);
+ dbg_fsbuild("Blocks required to allow GC merges: %d (%d KiB)\n",
+ c->resv_blocks_gcmerge, c->resv_blocks_gcmerge*c->sector_size/1024);
+ dbg_fsbuild("Blocks required to GC bad blocks: %d (%d KiB)\n",
+ c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024);
+ dbg_fsbuild("Amount of dirty space required to GC: %d bytes\n",
+ c->nospc_dirty_size);
}
int jffs2_do_mount_fs(struct jffs2_sb_info *c)
@@ -358,7 +352,7 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c)
return ret;
if (jffs2_build_filesystem(c)) {
- D1(printk(KERN_DEBUG "build_fs failed\n"));
+ dbg_fsbuild("build_fs failed\n");
jffs2_free_ino_caches(c);
jffs2_free_raw_node_refs(c);
#ifndef __ECOS
diff --git a/fs/jffs2/debug.c b/fs/jffs2/debug.c
index 28983501bce..0947284f45d 100644
--- a/fs/jffs2/debug.c
+++ b/fs/jffs2/debug.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: debug.c,v 1.10 2005/09/14 16:57:32 dedekind Exp $
+ * $Id: debug.c,v 1.11 2005/09/21 13:28:35 dedekind Exp $
*
*/
#include <linux/kernel.h>
@@ -15,6 +15,7 @@
#include <linux/pagemap.h>
#include <linux/crc32.h>
#include <linux/jffs2.h>
+#include <linux/mtd/mtd.h>
#include "nodelist.h"
#include "debug.h"
diff --git a/fs/jffs2/debug.h b/fs/jffs2/debug.h
index 7328e67bebb..da1417d3891 100644
--- a/fs/jffs2/debug.h
+++ b/fs/jffs2/debug.h
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: debug.h,v 1.16 2005/09/14 16:57:32 dedekind Exp $
+ * $Id: debug.h,v 1.18 2005/09/21 10:26:26 dedekind Exp $
*
*/
#ifndef _JFFS2_DEBUG_H_
@@ -23,16 +23,23 @@
/* Enable "paranoia" checks and dumps */
#define JFFS2_DBG_PARANOIA_CHECKS
#define JFFS2_DBG_DUMPS
+
+/*
+ * By defining/undefining the below macros one may select debugging messages
+ * fro specific JFFS2 subsystems.
+ */
#define JFFS2_DBG_READINODE_MESSAGES
#define JFFS2_DBG_FRAGTREE_MESSAGES
#define JFFS2_DBG_DENTLIST_MESSAGES
#define JFFS2_DBG_NODEREF_MESSAGES
#define JFFS2_DBG_INOCACHE_MESSAGES
#define JFFS2_DBG_SUMMARY_MESSAGES
+#define JFFS2_DBG_FSBUILD_MESSAGES
#endif
#if CONFIG_JFFS2_FS_DEBUG == 2
#define JFFS2_DBG_FRAGTREE2_MESSAGES
+#define JFFS2_DBG_MEMALLOC_MESSAGES
#endif
/* Sanity checks are supposed to be light-weight and enabled by default */
@@ -40,7 +47,7 @@
/*
* Dx() are mainly used for debugging messages, they must go away and be
- * superseded by nicer JFFS2_DBG_XXX() macros...
+ * superseded by nicer dbg_xxx() macros...
*/
#if CONFIG_JFFS2_FS_DEBUG > 0
#define D1(x) x
@@ -105,56 +112,63 @@
*/
/* Read inode debugging messages */
#ifdef JFFS2_DBG_READINODE_MESSAGES
-#define JFFS2_DBG_READINODE(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#define dbg_readinode(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
#else
-#define JFFS2_DBG_READINODE(fmt, ...)
+#define dbg_readinode(fmt, ...)
#endif
/* Fragtree build debugging messages */
#ifdef JFFS2_DBG_FRAGTREE_MESSAGES
-#define JFFS2_DBG_FRAGTREE(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
#else
-#define JFFS2_DBG_FRAGTREE(fmt, ...)
+#define dbg_fragtree(fmt, ...)
#endif
#ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
-#define JFFS2_DBG_FRAGTREE2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#define dbg_fragtree2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
#else
-#define JFFS2_DBG_FRAGTREE2(fmt, ...)
+#define dbg_fragtree2(fmt, ...)
#endif
/* Directory entry list manilulation debugging messages */
#ifdef JFFS2_DBG_DENTLIST_MESSAGES
-#define JFFS2_DBG_DENTLIST(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
#else
-#define JFFS2_DBG_DENTLIST(fmt, ...)
+#define dbg_dentlist(fmt, ...)
#endif
/* Print the messages about manipulating node_refs */
#ifdef JFFS2_DBG_NODEREF_MESSAGES
-#define JFFS2_DBG_NODEREF(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#define dbg_noderef(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
#else
-#define JFFS2_DBG_NODEREF(fmt, ...)
+#define dbg_noderef(fmt, ...)
#endif
/* Manipulations with the list of inodes (JFFS2 inocache) */
#ifdef JFFS2_DBG_INOCACHE_MESSAGES
-#define JFFS2_DBG_INOCACHE(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
#else
-#define JFFS2_DBG_INOCACHE(fmt, ...)
+#define dbg_inocache(fmt, ...)
#endif
/* Summary debugging messages */
#ifdef JFFS2_DBG_SUMMARY_MESSAGES
-#define JFFS2_DBG_SUMMARY(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#define dbg_summary(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#else
+#define dbg_summary(fmt, ...)
+#endif
+
+/* File system build messages */
+#ifdef JFFS2_DBG_FSBUILD_MESSAGES
+#define dbg_fsbuild(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
#else
-#define JFFS2_DBG_SUMMARY(fmt, ...)
+#define dbg_fsbuild(fmt, ...)
#endif
/* Watch the object allocations */
#ifdef JFFS2_DBG_MEMALLOC_MESSAGES
-#define JFFS2_DBG_MEMALLOC(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
+#define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
#else
-#define JFFS2_DBG_MEMALLOC(fmt, ...)
+#define dbg_memalloc(fmt, ...)
#endif
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index a8a0908142d..347de4efeee 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: erase.c,v 1.83 2005/07/22 10:32:08 dedekind Exp $
+ * $Id: erase.c,v 1.85 2005/09/20 14:53:15 dedekind Exp $
*
*/
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c
index 734801145bf..f27df015f3e 100644
--- a/fs/jffs2/malloc.c
+++ b/fs/jffs2/malloc.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: malloc.c,v 1.29 2005/07/27 14:16:53 dedekind Exp $
+ * $Id: malloc.c,v 1.30 2005/09/20 14:27:34 dedekind Exp $
*
*/
@@ -97,13 +97,13 @@ struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize)
{
struct jffs2_full_dirent *ret;
ret = kmalloc(sizeof(struct jffs2_full_dirent) + namesize, GFP_KERNEL);
- JFFS2_DBG_MEMALLOC("%p\n", ret);
+ dbg_memalloc("%p\n", ret);
return ret;
}
void jffs2_free_full_dirent(struct jffs2_full_dirent *x)
{
- JFFS2_DBG_MEMALLOC("%p\n", x);
+ dbg_memalloc("%p\n", x);
kfree(x);
}
@@ -111,13 +111,13 @@ struct jffs2_full_dnode *jffs2_alloc_full_dnode(void)
{
struct jffs2_full_dnode *ret;
ret = kmem_cache_alloc(full_dnode_slab, GFP_KERNEL);
- JFFS2_DBG_MEMALLOC("%p\n", ret);
+ dbg_memalloc("%p\n", ret);
return ret;
}
void jffs2_free_full_dnode(struct jffs2_full_dnode *x)
{
- JFFS2_DBG_MEMALLOC("%p\n", x);
+ dbg_memalloc("%p\n", x);
kmem_cache_free(full_dnode_slab, x);
}
@@ -125,13 +125,13 @@ struct jffs2_raw_dirent *jffs2_alloc_raw_dirent(void)
{
struct jffs2_raw_dirent *ret;
ret = kmem_cache_alloc(raw_dirent_slab, GFP_KERNEL);
- JFFS2_DBG_MEMALLOC("%p\n", ret);
+ dbg_memalloc("%p\n", ret);
return ret;
}
void jffs2_free_raw_dirent(struct jffs2_raw_dirent *x)
{
- JFFS2_DBG_MEMALLOC("%p\n", x);
+ dbg_memalloc("%p\n", x);
kmem_cache_free(raw_dirent_slab, x);
}
@@ -139,13 +139,13 @@ struct jffs2_raw_inode *jffs2_alloc_raw_inode(void)
{
struct jffs2_raw_inode *ret;
ret = kmem_cache_alloc(raw_inode_slab, GFP_KERNEL);
- JFFS2_DBG_MEMALLOC("%p\n", ret);
+ dbg_memalloc("%p\n", ret);
return ret;
}
void jffs2_free_raw_inode(struct jffs2_raw_inode *x)
{
- JFFS2_DBG_MEMALLOC("%p\n", x);
+ dbg_memalloc("%p\n", x);
kmem_cache_free(raw_inode_slab, x);
}
@@ -153,14 +153,14 @@ struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void)
{
struct jffs2_tmp_dnode_info *ret;
ret = kmem_cache_alloc(tmp_dnode_info_slab, GFP_KERNEL);
- JFFS2_DBG_MEMALLOC("%p\n",
+ dbg_memalloc("%p\n",
ret);
return ret;
}
void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x)
{
- JFFS2_DBG_MEMALLOC("%p\n", x);
+ dbg_memalloc("%p\n", x);
kmem_cache_free(tmp_dnode_info_slab, x);
}
@@ -168,13 +168,13 @@ struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void)
{
struct jffs2_raw_node_ref *ret;
ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL);
- JFFS2_DBG_MEMALLOC("%p\n", ret);
+ dbg_memalloc("%p\n", ret);
return ret;
}
void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x)
{
- JFFS2_DBG_MEMALLOC("%p\n", x);
+ dbg_memalloc("%p\n", x);
kmem_cache_free(raw_node_ref_slab, x);
}
@@ -182,13 +182,13 @@ struct jffs2_node_frag *jffs2_alloc_node_frag(void)
{
struct jffs2_node_frag *ret;
ret = kmem_cache_alloc(node_frag_slab, GFP_KERNEL);
- JFFS2_DBG_MEMALLOC("%p\n", ret);
+ dbg_memalloc("%p\n", ret);
return ret;
}
void jffs2_free_node_frag(struct jffs2_node_frag *x)
{
- JFFS2_DBG_MEMALLOC("%p\n", x);
+ dbg_memalloc("%p\n", x);
kmem_cache_free(node_frag_slab, x);
}
@@ -196,12 +196,12 @@ struct jffs2_inode_cache *jffs2_alloc_inode_cache(void)
{
struct jffs2_inode_cache *ret;
ret = kmem_cache_alloc(inode_cache_slab, GFP_KERNEL);
- JFFS2_DBG_MEMALLOC("%p\n", ret);
+ dbg_memalloc("%p\n", ret);
return ret;
}
void jffs2_free_inode_cache(struct jffs2_inode_cache *x)
{
- JFFS2_DBG_MEMALLOC("%p\n", x);
+ dbg_memalloc("%p\n", x);
kmem_cache_free(inode_cache_slab, x);
}
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
index 9abb5f4cfd7..80fe8feffb4 100644
--- a/fs/jffs2/nodelist.c
+++ b/fs/jffs2/nodelist.c
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
- * $Id: nodelist.c,v 1.112 2005/08/22 09:07:09 dedekind Exp $
+ * $Id: nodelist.c,v 1.114 2005/09/21 13:28:35 dedekind Exp $
*
*/
@@ -25,18 +25,18 @@ void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new
{
struct jffs2_full_dirent **prev = list;
- JFFS2_DBG_DENTLIST("add dirent \"%s\", ino #%u\n", new->name, new->ino);
+ dbg_dentlist("add dirent \"%s\", ino #%u\n", new->name, new->ino);
while ((*prev) && (*prev)->nhash <= new->nhash) {
if ((*prev)->nhash == new->nhash && !strcmp((*prev)->name, new->name)) {
/* Duplicate. Free one */
if (new->version < (*prev)->version) {
- JFFS2_DBG_DENTLIST("Eep! Marking new dirent node is obsolete, old is \"%s\", ino #%u\n",
+ dbg_dentlist("Eep! Marking new dirent node is obsolete, old is \"%s\", ino #%u\n",
(*prev)->name, (*prev)->ino);
jffs2_mark_node_obsolete(c, new->raw);
jffs2_free_full_dirent(new);
} else {
- JFFS2_DBG_DENTLIST("marking old dirent \"%s\", ino #%u bsolete\n",
+ dbg_dentlist("marking old dirent \"%s\", ino #%u bsolete\n",
(*prev)->name, (*prev)->ino);
new->next = (*prev)->next;
jffs2_mark_node_obsolete(c, ((*prev)->raw));
@@ -55,7 +55,7 @@ void jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint
{
struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size);
- JFFS2_DBG_FRAGTREE("truncating fragtree to 0x%08x bytes\n", size);
+ dbg_fragtree("truncating fragtree to 0x%08x bytes\n", size);
/* We know frag->ofs <= size. That's what lookup does for us */
if (frag && frag->ofs != size) {
@@ -81,7 +81,7 @@ void jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint
*/
frag = frag_last(list);
if (frag->node && (frag->ofs & (PAGE_CACHE_SIZE - 1)) == 0) {
- JFFS2_DBG_FRAGTREE2("marking the last fragment 0x%08x-0x%08x REF_PRISTINE.\n",
+ dbg_fragtree2("marking the last fragment 0x%08x-0x%08x REF_PRISTINE.\n",
frag->ofs, frag->ofs + frag->size);
frag->node->raw->flash_offset = ref_offset(frag->node->raw) | REF_PRISTINE;
}
@@ -93,12 +93,12 @@ void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *t
this->node->frags--;
if (!this->node->frags) {
/* The node has no valid frags left. It's totally obsoleted */
- JFFS2_DBG_FRAGTREE2("marking old node @0x%08x (0x%04x-0x%04x) obsolete\n",
+ dbg_fragtree2("marking old node @0x%08x (0x%04x-0x%04x) obsolete\n",
ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size);
jffs2_mark_node_obsolete(c, this->node->raw);
jffs2_free_full_dnode(this->node);
} else {
- JFFS2_DBG_FRAGTREE2("marking old node @0x%08x (0x%04x-0x%04x) REF_NORMAL. frags is %d\n",
+ dbg_fragtree2("marking old node @0x%08x (0x%04x-0x%04x) REF_NORMAL. frags is %d\n",
ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size, this->node->frags);
mark_ref_normal(this->node->raw);
}
@@ -112,7 +112,7 @@ static void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_
struct rb_node *parent = &base->rb;
struct rb_node **link = &parent;
- JFFS2_DBG_FRAGTREE2("insert frag (0x%04x-0x%04x)\n", newfrag->ofs, newfrag->ofs + newfrag->size);
+ dbg_fragtree2("insert frag (0x%04x-0x%04x)\n", newfrag->ofs, newfrag->ofs + newfrag->size);
while (*link) {
parent = *link;
@@ -172,11 +172,11 @@ static int no_overlapping_node(struct jffs2_sb_info *c, struct rb_root *root,
/* 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 */
- JFFS2_DBG_FRAGTREE2("add hole frag %#04x-%#04x on the right of the new frag.\n",
+ dbg_fragtree2("add hole frag %#04x-%#04x on the right of the new frag.\n",
holefrag->ofs, holefrag->ofs + holefrag->size);
rb_link_node(&holefrag->rb, &this->rb, &this->rb.rb_right);
} else {
- JFFS2_DBG_FRAGTREE2("Add hole frag %#04x-%#04x to the root of the tree.\n",
+ dbg_fragtree2("Add hole frag %#04x-%#04x to the root of the tree.\n",
holefrag->ofs, holefrag->ofs + holefrag->size);
rb_link_node(&holefrag->rb, NULL, &root->rb_node);
}
@@ -188,10 +188,10 @@ static int no_overlapping_node(struct jffs2_sb_info *c, struct rb_root *root,
/* 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 new fragment */
- JFFS2_DBG_FRAGTREE2("add the new node at the right\n");
+ dbg_fragtree2("add the new node at the right\n");
rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);
} else {
- JFFS2_DBG_FRAGTREE2("insert the new node at the root of the tree\n");
+ dbg_fragtree2("insert the new node at the root of the tree\n");
rb_link_node(&newfrag->rb, NULL, &root->rb_node);
}
rb_insert_color(&newfrag->rb, root);
@@ -209,11 +209,11 @@ static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *r
this = jffs2_lookup_node_frag(root, newfrag->node->ofs);
if (this) {
- JFFS2_DBG_FRAGTREE2("lookup gave frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n",
+ dbg_fragtree2("lookup gave 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);
lastend = this->ofs + this->size;
} else {
- JFFS2_DBG_FRAGTREE2("lookup gave no frag\n");
+ dbg_fragtree2("lookup gave no frag\n");
lastend = 0;
}
@@ -235,11 +235,11 @@ static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *r
}
if (this->node)
- JFFS2_DBG_FRAGTREE2("dealing with frag %u-%u, phys %#08x(%d).\n",
+ dbg_fragtree2("dealing with frag %u-%u, phys %#08x(%d).\n",
this->ofs, this->ofs + this->size,
ref_offset(this->node->raw), ref_flags(this->node->raw));
else
- JFFS2_DBG_FRAGTREE2("dealing with hole frag %u-%u.\n",
+ dbg_fragtree2("dealing with hole frag %u-%u.\n",
this->ofs, this->ofs + this->size);
/* OK. 'this' is pointing at the first frag that newfrag->ofs at least partially obsoletes,
@@ -259,10 +259,10 @@ static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *r
struct jffs2_node_frag *newfrag2;
if (this->node)
- JFFS2_DBG_FRAGTREE2("split old frag 0x%04x-0x%04x, phys 0x%08x\n",
+ dbg_fragtree2("split old frag 0x%04x-0x%04x, phys 0x%08x\n",
this->ofs, this->ofs+this->size, ref_offset(this->node->raw));
else
- JFFS2_DBG_FRAGTREE2("split old hole frag 0x%04x-0x%04x\n",
+ dbg_fragtree2("split old hole frag 0x%04x-0x%04x\n",
this->ofs, this->ofs+this->size);
/* New second frag pointing to this's node */
@@ -299,13 +299,13 @@ static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *r
} else {
/* New frag starts at the same point as 'this' used to. Replace
it in the tree without doing a delete and insertion */
- JFFS2_DBG_FRAGTREE2("inserting newfrag (*%p),%d-%d in before 'this' (*%p),%d-%d\n",
+ dbg_fragtree2("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, root);
if (newfrag->ofs + newfrag->size >= this->ofs+this->size) {
- JFFS2_DBG_FRAGTREE2("obsoleting node frag %p (%x-%x)\n", this, this->ofs, this->ofs+this->size);
+ dbg_fragtree2("obsoleting node frag %p (%x-%x)\n", this, this->ofs, this->ofs+this->size);
jffs2_obsolete_node_frag(c, this);
} else {
this->ofs += newfrag->size;
@@ -321,7 +321,7 @@ static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *r
*/
while ((this = frag_next(newfrag)) && newfrag->ofs + newfrag->size >= this->ofs + this->size) {
/* 'this' frag is obsoleted completely. */
- JFFS2_DBG_FRAGTREE2("obsoleting node frag %p (%x-%x) and removing from tree\n",
+ dbg_fragtree2("obsoleting node frag %p (%x-%x) and removing from tree\n",
this, this->ofs, this->ofs+this->size);
rb_erase(&this->rb, root);
jffs2_obsolete_node_frag(c, this);
@@ -361,7 +361,7 @@ int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_in
return -ENOMEM;
newfrag->node->frags = 1;
- JFFS2_DBG_FRAGTREE("adding node %#04x-%#04x @0x%08x on flash, newfrag *%p\n",
+ dbg_fragtree("adding node %#04x-%#04x @0x%08x on flash, newfrag *%p\n",
fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag);
ret = jffs2_add_frag_to_fragtree(c, &f->fragtree, newfrag);
@@ -410,14 +410,17 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
BUG_ON(tn->csize == 0);
+ if (!jffs2_is_writebuffered(c))
+ goto adj_acc;
+
/* Calculate how many bytes were already checked */
ofs = ref_offset(ref) + sizeof(struct jffs2_raw_inode);
- len = ofs & (c->wbuf_pagesize - 1);
+ len = ofs % c->wbuf_pagesize;
if (likely(len))
len = c->wbuf_pagesize - len;
if (len >= tn->csize) {
- JFFS2_DBG_READINODE("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n",
+ dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n",
ref_offset(ref), tn->csize, ofs);
goto adj_acc;
}
@@ -425,7 +428,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
ofs += len;
len = tn->csize - len;
- JFFS2_DBG_READINODE("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n",
+ dbg_readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n",
ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len);
#ifndef __ECOS
@@ -520,7 +523,7 @@ static inline int check_node(struct jffs2_sb_info *c, struct jffs2_inode_info *f
if (ref_flags(tn->fn->raw) != REF_UNCHECKED)
return 0;
- JFFS2_DBG_FRAGTREE2("check node %#04x-%#04x, phys offs %#08x.\