aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2')
-rw-r--r--fs/jffs2/Makefile4
-rw-r--r--fs/jffs2/build.c6
-rw-r--r--fs/jffs2/debug.c495
-rw-r--r--fs/jffs2/debug.h104
-rw-r--r--fs/jffs2/erase.c6
-rw-r--r--fs/jffs2/fs.c4
-rw-r--r--fs/jffs2/gc.c14
-rw-r--r--fs/jffs2/nodelist.h106
-rw-r--r--fs/jffs2/nodemgmt.c168
-rw-r--r--fs/jffs2/read.c4
-rw-r--r--fs/jffs2/readinode.c110
-rw-r--r--fs/jffs2/scan.c6
-rw-r--r--fs/jffs2/wbuf.c20
-rw-r--r--fs/jffs2/write.c55
14 files changed, 663 insertions, 439 deletions
diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile
index f1afe681ecd6..e6230f1bba73 100644
--- a/fs/jffs2/Makefile
+++ b/fs/jffs2/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# Makefile for the Linux Journalling Flash File System v2 (JFFS2) 2# Makefile for the Linux Journalling Flash File System v2 (JFFS2)
3# 3#
4# $Id: Makefile.common,v 1.9 2005/02/09 09:23:53 pavlov Exp $ 4# $Id: Makefile.common,v 1.10 2005/07/17 06:56:20 dedekind Exp $
5# 5#
6 6
7obj-$(CONFIG_JFFS2_FS) += jffs2.o 7obj-$(CONFIG_JFFS2_FS) += jffs2.o
@@ -9,7 +9,7 @@ obj-$(CONFIG_JFFS2_FS) += jffs2.o
9jffs2-y := compr.o dir.o file.o ioctl.o nodelist.o malloc.o 9jffs2-y := compr.o dir.o file.o ioctl.o nodelist.o malloc.o
10jffs2-y += read.o nodemgmt.o readinode.o write.o scan.o gc.o 10jffs2-y += read.o nodemgmt.o readinode.o write.o scan.o gc.o
11jffs2-y += symlink.o build.o erase.o background.o fs.o writev.o 11jffs2-y += symlink.o build.o erase.o background.o fs.o writev.o
12jffs2-y += super.o 12jffs2-y += super.o debug.o
13 13
14jffs2-$(CONFIG_JFFS2_FS_WRITEBUFFER) += wbuf.o 14jffs2-$(CONFIG_JFFS2_FS_WRITEBUFFER) += wbuf.o
15jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o 15jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
index 97dc39796e2c..3a0b003d73a1 100644
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: build.c,v 1.71 2005/07/12 16:37:08 dedekind Exp $ 10 * $Id: build.c,v 1.72 2005/07/17 06:56:20 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -104,7 +104,7 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
104 goto exit; 104 goto exit;
105 105
106 D1(printk(KERN_DEBUG "Scanned flash completely\n")); 106 D1(printk(KERN_DEBUG "Scanned flash completely\n"));
107 D2(jffs2_dump_block_lists(c)); 107 D2(jffs2_dbg_dump_block_lists(c));
108 108
109 c->flags |= JFFS2_SB_FLAG_BUILDING; 109 c->flags |= JFFS2_SB_FLAG_BUILDING;
110 /* Now scan the directory tree, increasing nlink according to every dirent found. */ 110 /* Now scan the directory tree, increasing nlink according to every dirent found. */
@@ -168,7 +168,7 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
168 c->flags &= ~JFFS2_SB_FLAG_BUILDING; 168 c->flags &= ~JFFS2_SB_FLAG_BUILDING;
169 169
170 D1(printk(KERN_DEBUG "Pass 3 complete\n")); 170 D1(printk(KERN_DEBUG "Pass 3 complete\n"));
171 D2(jffs2_dump_block_lists(c)); 171 D2(jffs2_dbg_dump_block_lists(c));
172 172
173 /* Rotate the lists by some number to ensure wear levelling */ 173 /* Rotate the lists by some number to ensure wear levelling */
174 jffs2_rotate_lists(c); 174 jffs2_rotate_lists(c);
diff --git a/fs/jffs2/debug.c b/fs/jffs2/debug.c
new file mode 100644
index 000000000000..9da524ca4e66
--- /dev/null
+++ b/fs/jffs2/debug.c
@@ -0,0 +1,495 @@
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2001-2003 Red Hat, Inc.
5 *
6 * Created by David Woodhouse <dwmw2@infradead.org>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
10 * $Id: debug.c,v 1.1 2005/07/17 06:56:20 dedekind Exp $
11 *
12 */
13#include <linux/kernel.h>
14#include <linux/pagemap.h>
15#include "nodelist.h"
16#include "debug.h"
17
18#ifdef JFFS2_DBG_PARANOIA_CHECKS
19
20void
21jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f)
22{
23 struct jffs2_node_frag *frag;
24 int bitched = 0;
25
26 for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
27 struct jffs2_full_dnode *fn = frag->node;
28
29 if (!fn || !fn->raw)
30 continue;
31
32 if (ref_flags(fn->raw) == REF_PRISTINE) {
33 if (fn->frags > 1) {
34 printk(KERN_ERR "REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2\n",
35 ref_offset(fn->raw), fn->frags);
36 bitched = 1;
37 }
38
39 /* A hole node which isn't multi-page should be garbage-collected
40 and merged anyway, so we just check for the frag size here,
41 rather than mucking around with actually reading the node
42 and checking the compression type, which is the real way
43 to tell a hole node. */
44 if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag)
45 && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) {
46 printk(KERN_ERR "REF_PRISTINE node at 0x%08x had a previous non-hole frag "
47 "in the same page. Tell dwmw2\n", ref_offset(fn->raw));
48 bitched = 1;
49 }
50
51 if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag)
52 && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) {
53 printk(KERN_ERR "REF_PRISTINE node at 0x%08x (%08x-%08x) had a following "
54 "non-hole frag in the same page. Tell dwmw2\n",
55 ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size);
56 bitched = 1;
57 }
58 }
59 }
60
61 if (bitched) {
62 printk(KERN_ERR "Fragtree is corrupted. Fragtree dump:\n");
63 jffs2_dbg_dump_fragtree(f);
64 BUG();
65 }
66}
67
68/*
69 * Check if the flash contains all 0xFF before we start writing.
70 */
71void
72jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c, uint32_t ofs, int len)
73{
74 size_t retlen;
75 int ret, i;
76 unsigned char *buf;
77
78 buf = kmalloc(len, GFP_KERNEL);
79 if (!buf)
80 return;
81
82 ret = jffs2_flash_read(c, ofs, len, &retlen, buf);
83 if (ret || (retlen != len)) {
84 printk(KERN_WARNING "read %d bytes failed or short in %s(). ret %d, retlen %zd\n",
85 len, __FUNCTION__, ret, retlen);
86 kfree(buf);
87 return;
88 }
89
90 ret = 0;
91 for (i = 0; i < len; i++)
92 if (buf[i] != 0xff)
93 ret = 1;
94
95 if (ret) {
96 printk(KERN_ERR "ARGH. About to write node to %#08x on flash, but there are data "
97 "already there. The first corrupted byte is at %#08x.\n", ofs, ofs + i);
98 jffs2_dbg_dump_buffer(buf, len, ofs);
99 kfree(buf);
100 BUG();
101 }
102
103 kfree(buf);
104}
105
106/*
107 * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
108 */
109void
110jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
111{
112 uint32_t my_used_size = 0;
113 uint32_t my_unchecked_size = 0;
114 uint32_t my_dirty_size = 0;
115 struct jffs2_raw_node_ref *ref2 = jeb->first_node;
116
117 while (ref2) {
118 uint32_t totlen = ref_totlen(c, jeb, ref2);
119
120 if (ref2->flash_offset < jeb->offset ||
121 ref2->flash_offset > jeb->offset + c->sector_size) {
122 printk(KERN_ERR "node_ref %#08x shouldn't be in block at %#08x!\n",
123 ref_offset(ref2), jeb->offset);
124 jffs2_dbg_dump_node_refs(c, jeb);
125 jffs2_dbg_dump_block_lists(c);
126 BUG();
127
128 }
129 if (ref_flags(ref2) == REF_UNCHECKED)
130 my_unchecked_size += totlen;
131 else if (!ref_obsolete(ref2))
132 my_used_size += totlen;
133 else
134 my_dirty_size += totlen;
135
136 if ((!ref2->next_phys) != (ref2 == jeb->last_node)) {
137 printk(KERN_ERR "node_ref for node at %#08x (mem %p) has next_phys at %#08x (mem %p), "
138 "last_node is at %#08x (mem %p)\n",
139 ref_offset(ref2), ref2, ref_offset(ref2->next_phys), ref2->next_phys,
140 ref_offset(jeb->last_node), jeb->last_node);
141 jffs2_dbg_dump_node_refs(c, jeb);
142 jffs2_dbg_dump_block_lists(c);
143 BUG();
144 }
145 ref2 = ref2->next_phys;
146 }
147
148 if (my_used_size != jeb->used_size) {
149 printk(KERN_ERR "Calculated used size %#08x != stored used size %#08x\n",
150 my_used_size, jeb->used_size);
151 jffs2_dbg_dump_node_refs(c, jeb);
152 jffs2_dbg_dump_block_lists(c);
153 BUG();
154 }
155
156 if (my_unchecked_size != jeb->unchecked_size) {
157 printk(KERN_ERR "Calculated unchecked size %#08x != stored unchecked size %#08x\n",
158 my_unchecked_size, jeb->unchecked_size);
159 jffs2_dbg_dump_node_refs(c, jeb);
160 jffs2_dbg_dump_block_lists(c);
161 BUG();
162 }
163
164 if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) {
165 printk(KERN_ERR "Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n",
166 my_dirty_size, jeb->dirty_size + jeb->wasted_size);
167 jffs2_dbg_dump_node_refs(c, jeb);
168 jffs2_dbg_dump_block_lists(c);
169 BUG();
170 }
171
172 if (jeb->free_size == 0
173 && my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) {
174 printk(KERN_ERR "The sum of all nodes in block (%#x) != size of block (%#x)\n",
175 my_used_size + my_unchecked_size + my_dirty_size,
176 c->sector_size);
177 jffs2_dbg_dump_node_refs(c, jeb);
178 jffs2_dbg_dump_block_lists(c);
179 BUG();
180 }
181}
182#endif /* JFFS2_PARANOIA_CHECKS */
183
184#if defined(JFFS2_PARANOIA_CHECKS) || (CONFIG_JFFS2_FS_DEBUG > 0)
185/*
186 * Dump the node_refs of the 'jeb' JFFS2 eraseblock.
187 */
188void
189jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
190{
191 struct jffs2_raw_node_ref *ref;
192 int i = 0;
193
194 if (!jeb->first_node) {
195 printk(KERN_DEBUG "no nodes in block %#08x\n", jeb->offset);
196 return;
197 }
198
199 printk(KERN_DEBUG);
200 for (ref = jeb->first_node; ; ref = ref->next_phys) {
201 printk("%#08x(%#x)", ref_offset(ref), ref->__totlen);
202 if (ref->next_phys)
203 printk("->");
204 else
205 break;
206 if (++i == 4) {
207 i = 0;
208 printk("\n" KERN_DEBUG);
209 }
210 }
211 printk("\n");
212}
213
214void
215jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c)
216{
217 printk(KERN_DEBUG "flash_size: %#08x\n", c->flash_size);
218 printk(KERN_DEBUG "used_size: %#08x\n", c->used_size);
219 printk(KERN_DEBUG "dirty_size: %#08x\n", c->dirty_size);
220 printk(KERN_DEBUG "wasted_size: %#08x\n", c->wasted_size);
221 printk(KERN_DEBUG "unchecked_size: %#08x\n", c->unchecked_size);
222 printk(KERN_DEBUG "free_size: %#08x\n", c->free_size);
223 printk(KERN_DEBUG "erasing_size: %#08x\n", c->erasing_size);
224 printk(KERN_DEBUG "bad_size: %#08x\n", c->bad_size);
225 printk(KERN_DEBUG "sector_size: %#08x\n", c->sector_size);
226 printk(KERN_DEBUG "jffs2_reserved_blocks size: %#08x\n",
227 c->sector_size * c->resv_blocks_write);
228
229 if (c->nextblock)
230 printk(KERN_DEBUG "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
231 "unchecked %#08x, free %#08x)\n",
232 c->nextblock->offset, c->nextblock->used_size,
233 c->nextblock->dirty_size, c->nextblock->wasted_size,
234 c->nextblock->unchecked_size, c->nextblock->free_size);
235 else
236 printk(KERN_DEBUG "nextblock: NULL\n");
237
238 if (c->gcblock)
239 printk(KERN_DEBUG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
240 "unchecked %#08x, free %#08x)\n",
241 c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size,
242 c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
243 else
244 printk(KERN_DEBUG "gcblock: NULL\n");
245
246 if (list_empty(&c->clean_list)) {
247 printk(KERN_DEBUG "clean_list: empty\n");
248 } else {
249 struct list_head *this;
250 int numblocks = 0;
251 uint32_t dirty = 0;
252
253 list_for_each(this, &c->clean_list) {
254 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
255 numblocks ++;
256 dirty += jeb->wasted_size;
257 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
258 printk(KERN_DEBUG "clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
259 "unchecked %#08x, free %#08x)\n",
260 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
261 jeb->unchecked_size, jeb->free_size);
262 }
263 }
264
265 printk (KERN_DEBUG "Contains %d blocks with total wasted size %u, average wasted size: %u\n",
266 numblocks, dirty, dirty / numblocks);
267 }
268
269 if (list_empty(&c->very_dirty_list)) {
270 printk(KERN_DEBUG "very_dirty_list: empty\n");
271 } else {
272 struct list_head *this;
273 int numblocks = 0;
274 uint32_t dirty = 0;
275
276 list_for_each(this, &c->very_dirty_list) {
277 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
278
279 numblocks ++;
280 dirty += jeb->dirty_size;
281 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
282 printk(KERN_DEBUG "very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
283 "unchecked %#08x, free %#08x)\n",
284 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
285 jeb->unchecked_size, jeb->free_size);
286 }
287 }
288
289 printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
290 numblocks, dirty, dirty / numblocks);
291 }
292
293 if (list_empty(&c->dirty_list)) {
294 printk(KERN_DEBUG "dirty_list: empty\n");
295 } else {
296 struct list_head *this;
297 int numblocks = 0;
298 uint32_t dirty = 0;
299
300 list_for_each(this, &c->dirty_list) {
301 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
302
303 numblocks ++;
304 dirty += jeb->dirty_size;
305 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
306 printk(KERN_DEBUG "dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
307 "unchecked %#08x, free %#08x)\n",
308 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
309 jeb->unchecked_size, jeb->free_size);
310 }
311 }
312
313 printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
314 numblocks, dirty, dirty / numblocks);
315 }
316
317 if (list_empty(&c->erasable_list)) {
318 printk(KERN_DEBUG "erasable_list: empty\n");
319 } else {
320 struct list_head *this;
321
322 list_for_each(this, &c->erasable_list) {
323 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
324
325 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
326 printk(KERN_DEBUG "erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
327 "unchecked %#08x, free %#08x)\n",
328 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
329 jeb->unchecked_size, jeb->free_size);
330 }
331 }
332 }
333
334 if (list_empty(&c->erasing_list)) {
335 printk(KERN_DEBUG "erasing_list: empty\n");
336 } else {
337 struct list_head *this;
338
339 list_for_each(this, &c->erasing_list) {
340 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
341
342 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
343 printk(KERN_DEBUG "erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
344 "unchecked %#08x, free %#08x)\n",
345 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
346 jeb->unchecked_size, jeb->free_size);
347 }
348 }
349 }
350
351 if (list_empty(&c->erase_pending_list)) {
352 printk(KERN_DEBUG "erase_pending_list: empty\n");
353 } else {
354 struct list_head *this;
355
356 list_for_each(this, &c->erase_pending_list) {
357 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
358
359 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
360 printk(KERN_DEBUG "erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
361 "unchecked %#08x, free %#08x)\n",
362 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
363 jeb->unchecked_size, jeb->free_size);
364 }
365 }
366 }
367
368 if (list_empty(&c->erasable_pending_wbuf_list)) {
369 printk(KERN_DEBUG "erasable_pending_wbuf_list: empty\n");
370 } else {
371 struct list_head *this;
372
373 list_for_each(this, &c->erasable_pending_wbuf_list) {
374 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
375
376 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
377 printk(KERN_DEBUG "erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, "
378 "wasted %#08x, unchecked %#08x, free %#08x)\n",
379 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
380 jeb->unchecked_size, jeb->free_size);
381 }
382 }
383 }
384
385 if (list_empty(&c->free_list)) {
386 printk(KERN_DEBUG "free_list: empty\n");
387 } else {
388 struct list_head *this;
389
390 list_for_each(this, &c->free_list) {
391 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
392
393 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
394 printk(KERN_DEBUG "free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
395 "unchecked %#08x, free %#08x)\n",
396 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
397 jeb->unchecked_size, jeb->free_size);
398 }
399 }
400 }
401
402 if (list_empty(&c->bad_list)) {
403 printk(KERN_DEBUG "bad_list: empty\n");
404 } else {
405 struct list_head *this;
406
407 list_for_each(this, &c->bad_list) {
408 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
409
410 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
411 printk(KERN_DEBUG "bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
412 "unchecked %#08x, free %#08x)\n",
413 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
414 jeb->unchecked_size, jeb->free_size);
415 }
416 }
417 }
418
419 if (list_empty(&c->bad_used_list)) {
420 printk(KERN_DEBUG "bad_used_list: empty\n");
421 } else {
422 struct list_head *this;
423
424 list_for_each(this, &c->bad_used_list) {
425 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
426
427 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
428 printk(KERN_DEBUG "bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, "
429 "unchecked %#08x, free %#08x)\n",
430 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
431 jeb->unchecked_size, jeb->free_size);
432 }
433 }
434 }
435}
436
437void
438jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f)
439{
440 struct jffs2_node_frag *this = frag_first(&f->fragtree);
441 uint32_t lastofs = 0;
442 int buggy = 0;
443
444 printk(KERN_DEBUG "inode is ino #%u\n", f->inocache->ino);
445 while(this) {
446 if (this->node)
447 printk(KERN_DEBUG "frag %#04x-%#04x: %#08x(%d) on flash (*%p), left (%p), "
448 "right (%p), parent (%p)\n",
449 this->ofs, this->ofs+this->size, ref_offset(this->node->raw),
450 ref_flags(this->node->raw), this, frag_left(this), frag_right(this),
451 frag_parent(this));
452 else
453 printk(KERN_DEBUG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n",
454 this->ofs, this->ofs+this->size, this, frag_left(this),
455 frag_right(this), frag_parent(this));
456 if (this->ofs != lastofs)
457 buggy = 1;
458 lastofs = this->ofs + this->size;
459 this = frag_next(this);
460 }
461
462 if (f->metadata)
463 printk(KERN_DEBUG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
464
465 if (buggy) {
466 printk(KERN_ERR "Error! %s(): Frag tree got a hole in it\n", __FUNCTION__);
467 BUG();
468 }
469}
470
471#define JFFS3_BUFDUMP_BYTES_PER_LINE 8
472void
473jffs2_dbg_dump_buffer(char *buf, int len, uint32_t offs)
474{
475 int i = 0;
476 int skip = offs & ~(JFFS3_BUFDUMP_BYTES_PER_LINE - 1);
477
478 while (i < len) {
479 int j = 0;
480
481 printk(KERN_DEBUG "0x#x: \n");
482 while (skip) {
483 printk(" ");
484 skip -= 1;
485 }
486
487 while (j < JFFS3_BUFDUMP_BYTES_PER_LINE) {
488 if (i + j < len)
489 printk(" %#02x", buf[i + j++]);
490 }
491
492 i += JFFS3_BUFDUMP_BYTES_PER_LINE;
493 }
494}
495#endif /* JFFS2_PARANOIA_CHECKS || CONFIG_JFFS2_FS_DEBUG > 0 */
diff --git a/fs/jffs2/debug.h b/fs/jffs2/debug.h
new file mode 100644
index 000000000000..7d14f7b01397
--- /dev/null
+++ b/fs/jffs2/debug.h
@@ -0,0 +1,104 @@
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright (C) 2001-2003 Red Hat, Inc.
5 *
6 * Created by David Woodhouse <dwmw2@infradead.org>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
10 * $Id: debug.h,v 1.1 2005/07/17 06:56:20 dedekind Exp $
11 *
12 */
13#ifndef _JFFS2_DEBUG_H_
14#define _JFFS2_DEBUG_H_
15
16#include <linux/config.h>
17
18#ifndef CONFIG_JFFS2_FS_DEBUG
19#define CONFIG_JFFS2_FS_DEBUG 1
20#endif
21
22#if CONFIG_JFFS2_FS_DEBUG > 0
23#define JFFS2_DBG_PARANOIA_CHECKS
24#define D1(x) x
25#else
26#define D1(x)
27#endif
28
29#if CONFIG_JFFS2_FS_DEBUG > 1
30#define D2(x) x
31#else
32#define D2(x)
33#endif
34
35/* Enable JFFS2 sanity checks */
36#define JFFS2_DBG_SANITY_CHECKS
37
38#if CONFIG_JFFS2_FS_DEBUG > 0
39void
40jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c);
41
42void
43jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
44
45void
46jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f);
47
48void
49jffs2_dbg_dump_buffer(char *buf, int len, uint32_t offs);
50#endif
51
52#ifdef JFFS2_DBG_PARANOIA_CHECKS
53void
54jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f);
55
56void
57jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c,
58 struct jffs2_eraseblock *jeb);
59
60void
61jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
62 uint32_t ofs, int len);
63#else
64#define jffs2_dbg_fragtree_paranoia_check(f)
65#define jffs2_dbg_acct_paranoia_check(c, jeb)
66#define jffs2_dbg_prewrite_paranoia_check(c, ofs, len)
67#endif /* !JFFS2_PARANOIA_CHECKS */
68
69#ifdef JFFS2_DBG_SANITY_CHECKS
70/*
71 * Check the space accounting of the file system and of
72 * the JFFS3 erasable block 'jeb'.
73 */
74static inline void
75jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c,
76 struct jffs2_eraseblock *jeb)
77{
78 if (unlikely(jeb && jeb->used_size + jeb->dirty_size +
79 jeb->free_size + jeb->wasted_size +
80 jeb->unchecked_size != c->sector_size)) {
81 printk(KERN_ERR "Eeep. Space accounting for block at 0x%08x is screwed\n", jeb->offset);
82 printk(KERN_ERR "free %#08x + dirty %#08x + used %#08x + wasted %#08x + unchecked "
83 "%#08x != total %#08x\n", jeb->free_size, jeb->dirty_size, jeb->used_size,
84 jeb->wasted_size, jeb->unchecked_size, c->sector_size);
85 BUG();
86 }
87
88 if (unlikely(c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size
89 + c->wasted_size + c->unchecked_size != c->flash_size)) {
90 printk(KERN_ERR "Eeep. Space accounting superblock info is screwed\n");
91 printk(KERN_ERR "free %#08x + dirty %#08x + used %#08x + erasing %#08x + bad %#08x + "
92 "wasted %#08x + unchecked %#08x != total %#08x\n",
93 c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size,
94 c->wasted_size, c->unchecked_size, c->flash_size);
95 BUG();
96 }
97}
98#else
99static inline void
100jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c,
101 struct jffs2_eraseblock *jeb);
102#endif /* !JFFS2_DBG_SANITY_CHECKS */
103
104#endif /* _JFFS2_DEBUG_H_ */
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index 787d84ac2bcd..af0c7d431883 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: erase.c,v 1.80 2005/07/14 19:46:24 joern Exp $ 10 * $Id: erase.c,v 1.81 2005/07/17 06:56:20 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -429,8 +429,8 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
429 c->free_size += jeb->free_size; 429 c->free_size += jeb->free_size;
430 c->used_size += jeb->used_size; 430 c->used_size += jeb->used_size;
431 431
432 ACCT_SANITY_CHECK(c,jeb); 432 jffs2_dbg_acct_sanity_check(c,jeb);
433 D1(ACCT_PARANOIA_CHECK(jeb)); 433 jffs2_dbg_acct_paranoia_check(c, jeb);
434 434
435 list_add_tail(&jeb->list, &c->free_list); 435 list_add_tail(&jeb->list, &c->free_list);
436 c->nr_erasing_blocks--; 436 c->nr_erasing_blocks--;
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 5687c3f42002..6c8a9d5d56a4 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: fs.c,v 1.56 2005/07/06 12:13:09 dwmw2 Exp $ 10 * $Id: fs.c,v 1.57 2005/07/17 06:56:21 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -203,7 +203,7 @@ int jffs2_statfs(struct super_block *sb, struct kstatfs *buf)
203 203
204 buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT; 204 buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT;
205 205
206 D2(jffs2_dump_block_lists(c)); 206 D2(jffs2_dbg_dump_block_lists(c));
207 207
208 spin_unlock(&c->erase_completion_lock); 208 spin_unlock(&c->erase_completion_lock);
209 209
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index 7086cd634503..337ab49ab24b 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: gc.c,v 1.148 2005/04/09 10:47:00 dedekind Exp $ 10 * $Id: gc.c,v 1.149 2005/07/17 06:56:21 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -111,7 +111,7 @@ again:
111 ret->wasted_size = 0; 111 ret->wasted_size = 0;
112 } 112 }
113 113
114 D2(jffs2_dump_block_lists(c)); 114 D2(jffs2_dbg_dump_block_lists(c));
115 return ret; 115 return ret;
116} 116}
117 117
@@ -142,7 +142,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
142 if (c->checked_ino > c->highest_ino) { 142 if (c->checked_ino > c->highest_ino) {
143 printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n", 143 printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n",
144 c->unchecked_size); 144 c->unchecked_size);
145 D2(jffs2_dump_block_lists(c)); 145 D2(jffs2_dbg_dump_block_lists(c));
146 spin_unlock(&c->erase_completion_lock); 146 spin_unlock(&c->erase_completion_lock);
147 BUG(); 147 BUG();
148 } 148 }
@@ -619,16 +619,16 @@ static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
619 619
620 D1(printk(KERN_DEBUG "Retrying failed write of REF_PRISTINE node.\n")); 620 D1(printk(KERN_DEBUG "Retrying failed write of REF_PRISTINE node.\n"));
621 621
622 ACCT_SANITY_CHECK(c,jeb); 622 jffs2_dbg_acct_sanity_check(c,jeb);
623 D1(ACCT_PARANOIA_CHECK(jeb)); 623 jffs2_dbg_acct_paranoia_check(c, jeb);
624 624
625 ret = jffs2_reserve_space_gc(c, rawlen, &phys_ofs, &dummy); 625 ret = jffs2_reserve_space_gc(c, rawlen, &phys_ofs, &dummy);
626 626
627 if (!ret) { 627 if (!ret) {
628 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", phys_ofs)); 628 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", phys_ofs));
629 629
630 ACCT_SANITY_CHECK(c,jeb); 630 jffs2_dbg_acct_sanity_check(c,jeb);
631 D1(ACCT_PARANOIA_CHECK(jeb)); 631 jffs2_dbg_acct_paranoia_check(c, jeb);
632 632
633 goto retry; 633 goto retry;
634 } 634 }
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index b34c397909ef..6802e0968d3e 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: nodelist.h,v 1.131 2005/07/05 21:03:07 dwmw2 Exp $ 10 * $Id: nodelist.h,v 1.132 2005/07/17 06:56:21 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -24,26 +24,10 @@
24#ifdef __ECOS 24#ifdef __ECOS
25#include "os-ecos.h" 25#include "os-ecos.h"
26#else 26#else
27#include <linux/mtd/compatmac.h> /* For min/max in older kernels */ 27#include <linux/mtd/compatmac.h> /* For compatibility with older kernels */
28#include "os-linux.h" 28#include "os-linux.h"
29#endif 29#endif
30 30
31#ifndef CONFIG_JFFS2_FS_DEBUG
32#define CONFIG_JFFS2_FS_DEBUG 1
33#endif
34
35#if CONFIG_JFFS2_FS_DEBUG > 0
36#define D1(x) x
37#else
38#define D1(x)
39#endif
40
41#if CONFIG_JFFS2_FS_DEBUG > 1
42#define D2(x) x
43#else
44#define D2(x)
45#endif
46
47#define JFFS2_NATIVE_ENDIAN 31#define JFFS2_NATIVE_ENDIAN
48 32
49/* Note we handle mode bits conversion from JFFS2 (i.e. Linux) to/from 33/* Note we handle mode bits conversion from JFFS2 (i.e. Linux) to/from
@@ -207,79 +191,6 @@ struct jffs2_eraseblock
207 struct jffs2_raw_node_ref *gc_node; /* Next node to be garbage collected */ 191 struct jffs2_raw_node_ref *gc_node; /* Next node to be garbage collected */
208}; 192};
209 193
210#define ACCT_SANITY_CHECK(c, jeb) do { \
211 struct jffs2_eraseblock *___j = jeb; \
212 if ((___j) && ___j->used_size + ___j->dirty_size + ___j->free_size + ___j->wasted_size + ___j->unchecked_size != c->sector_size) { \
213 printk(KERN_NOTICE "Eeep. Space accounting for block at 0x%08x is screwed\n", ___j->offset); \
214 printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x + wasted %08x + unchecked %08x != total %08x\n", \
215 ___j->free_size, ___j->dirty_size, ___j->used_size, ___j->wasted_size, ___j->unchecked_size, c->sector_size); \
216 BUG(); \
217 } \
218 if (c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size + c->wasted_size + c->unchecked_size != c->flash_size) { \
219 printk(KERN_NOTICE "Eeep. Space accounting superblock info is screwed\n"); \
220 printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x + erasing %08x + bad %08x + wasted %08x + unchecked %08x != total %08x\n", \
221 c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size, c->wasted_size, c->unchecked_size, c->flash_size); \
222 BUG(); \
223 } \
224} while(0)
225
226static inline void paranoia_failed_dump(struct jffs2_eraseblock *jeb)
227{
228 struct jffs2_raw_node_ref *ref;
229 int i=0;
230
231 printk(KERN_NOTICE);
232 for (ref = jeb->first_node; ref; ref = ref->next_phys) {
233 printk("%08x->", ref_offset(ref));
234 if (++i == 8) {
235 i = 0;
236 printk("\n" KERN_NOTICE);
237 }
238 }
239 printk("\n");
240}
241
242
243#define ACCT_PARANOIA_CHECK(jeb) do { \
244 uint32_t my_used_size = 0; \
245 uint32_t my_unchecked_size = 0; \
246 struct jffs2_raw_node_ref *ref2 = jeb->first_node; \
247 while (ref2) { \
248 if (unlikely(ref2->flash_offset < jeb->offset || \
249 ref2->flash_offset > jeb->offset + c->sector_size)) { \
250 printk(KERN_NOTICE "Node %08x shouldn't be in block at %08x!\n", \
251 ref_offset(ref2), jeb->offset); \
252 paranoia_failed_dump(jeb); \
253 BUG(); \
254 } \
255 if (ref_flags(ref2) == REF_UNCHECKED) \
256 my_unchecked_size += ref_totlen(c, jeb, ref2); \
257 else if (!ref_obsolete(ref2)) \
258 my_used_size += ref_totlen(c, jeb, ref2); \
259 if (unlikely((!ref2->next_phys) != (ref2 == jeb->last_node))) { \
260 if (!ref2->next_phys) \
261 printk("ref for node at %p (phys %08x) has next_phys->%p (----), last_node->%p (phys %08x)\n", \
262 ref2, ref_offset(ref2), ref2->next_phys, \
263 jeb->last_node, ref_offset(jeb->last_node)); \
264 else \
265 printk("ref for node at %p (phys %08x) has next_phys->%p (%08x), last_node->%p (phys %08x)\n", \
266 ref2, ref_offset(ref2), ref2->next_phys, ref_offset(ref2->next_phys), \
267 jeb->last_node, ref_offset(jeb->last_node)); \
268 paranoia_failed_dump(jeb); \
269 BUG(); \
270 } \
271 ref2 = ref2->next_phys; \
272 } \
273 if (my_used_size != jeb->used_size) { \
274 printk(KERN_NOTICE "Calculated used size %08x != stored used size %08x\n", my_used_size, jeb->used_size); \
275 BUG(); \
276 } \
277 if (my_unchecked_size != jeb->unchecked_size) { \
278 printk(KERN_NOTICE "Calculated unchecked size %08x != stored unchecked size %08x\n", my_unchecked_size, jeb->unchecked_size); \
279 BUG(); \
280 } \
281 } while(0)
282
283/* Calculate totlen from surrounding nodes or eraseblock */ 194/* Calculate totlen from surrounding nodes or eraseblock */
284static inline uint32_t __ref_totlen(struct jffs2_sb_info *c, 195static inline uint32_t __ref_totlen(struct jffs2_sb_info *c,
285 struct jffs2_eraseblock *jeb, 196 struct jffs2_eraseblock *jeb,
@@ -306,11 +217,13 @@ static inline uint32_t ref_totlen(struct jffs2_sb_info *c,
306{ 217{
307 uint32_t ret; 218 uint32_t ret;
308 219
309 D1(if (jeb && jeb != &c->blocks[ref->flash_offset / c->sector_size]) { 220#if CONFIG_JFFS2_FS_DEBUG > 0
221 if (jeb && jeb != &c->blocks[ref->flash_offset / c->sector_size]) {
310 printk(KERN_CRIT "ref_totlen called with wrong block -- at 0x%08x instead of 0x%08x; ref 0x%08x\n", 222 printk(KERN_CRIT "ref_totlen called with wrong block -- at 0x%08x instead of 0x%08x; ref 0x%08x\n",
311 jeb->offset, c->blocks[ref->flash_offset / c->sector_size].offset, ref_offset(ref)); 223 jeb->offset, c->blocks[ref->flash_offset / c->sector_size].offset, ref_offset(ref));
312 BUG(); 224 BUG();
313 }) 225 }
226#endif
314 227
315#if 1 228#if 1
316 ret = ref->__totlen; 229 ret = ref->__totlen;
@@ -323,14 +236,13 @@ static inline uint32_t ref_totlen(struct jffs2_sb_info *c,
323 ret, ref->__totlen); 236 ret, ref->__totlen);
324 if (!jeb) 237 if (!jeb)
325 jeb = &c->blocks[ref->flash_offset / c->sector_size]; 238 jeb = &c->blocks[ref->flash_offset / c->sector_size];
326 paranoia_failed_dump(jeb); 239 jffs2_dbg_dump_node_refs(c, jeb);
327 BUG(); 240 BUG();
328 } 241 }
329#endif 242#endif
330 return ret; 243 return ret;
331} 244}
332 245
333
334#define ALLOC_NORMAL 0 /* Normal allocation */ 246#define ALLOC_NORMAL 0 /* Normal allocation */
335#define ALLOC_DELETION 1 /* Deletion node. Best to allow it */ 247#define ALLOC_DELETION 1 /* Deletion node. Best to allow it */
336#define ALLOC_GC 2 /* Space requested for GC. Give it or die */ 248#define ALLOC_GC 2 /* Space requested for GC. Give it or die */
@@ -384,7 +296,6 @@ static inline struct jffs2_node_frag *frag_last(struct rb_root *root)
384#define frag_erase(frag, list) rb_erase(&frag->rb, list); 296#define frag_erase(frag, list) rb_erase(&frag->rb, list);
385 297
386/* nodelist.c */ 298/* nodelist.c */
387D2(void jffs2_print_frag_list(struct jffs2_inode_info *f));
388void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list); 299void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list);
389int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 300int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
390 struct rb_root *tnp, struct jffs2_full_dirent **fdp, 301 struct rb_root *tnp, struct jffs2_full_dirent **fdp,
@@ -410,7 +321,6 @@ int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *
410int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new); 321int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new);
411void jffs2_complete_reservation(struct jffs2_sb_info *c); 322void jffs2_complete_reservation(struct jffs2_sb_info *c);
412void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *raw); 323void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *raw);
413void jffs2_dump_block_lists(struct jffs2_sb_info *c);
414 324
415/* write.c */ 325/* write.c */
416int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri); 326int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri);
@@ -483,4 +393,6 @@ int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_erasebloc
483int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); 393int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
484#endif 394#endif
485 395
396#include "debug.h"
397
486#endif /* __JFFS2_NODELIST_H__ */ 398#endif /* __JFFS2_NODELIST_H__ */
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
index c1d8b5ed9ab9..424be1e1ca92 100644
--- a/fs/jffs2/nodemgmt.c
+++ b/fs/jffs2/nodemgmt.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: nodemgmt.c,v 1.122 2005/05/06 09:30:27 dedekind Exp $ 10 * $Id: nodemgmt.c,v 1.123 2005/07/17 06:56:21 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -349,8 +349,8 @@ int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_r
349 list_add_tail(&jeb->list, &c->clean_list); 349 list_add_tail(&jeb->list, &c->clean_list);
350 c->nextblock = NULL; 350 c->nextblock = NULL;
351 } 351 }
352 ACCT_SANITY_CHECK(c,jeb); 352 jffs2_dbg_acct_sanity_check(c,jeb);
353 D1(ACCT_PARANOIA_CHECK(jeb)); 353 jffs2_dbg_acct_paranoia_check(c, jeb);
354 354
355 spin_unlock(&c->erase_completion_lock); 355 spin_unlock(&c->erase_completion_lock);
356 356
@@ -466,9 +466,9 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
466 } 466 }
467 ref->flash_offset = ref_offset(ref) | REF_OBSOLETE; 467 ref->flash_offset = ref_offset(ref) | REF_OBSOLETE;
468 468
469 ACCT_SANITY_CHECK(c, jeb); 469 jffs2_dbg_acct_sanity_check(c, jeb);
470 470
471 D1(ACCT_PARANOIA_CHECK(jeb)); 471 jffs2_dbg_acct_paranoia_check(c, jeb);
472 472
473 if (c->flags & JFFS2_SB_FLAG_SCANNING) { 473 if (c->flags & JFFS2_SB_FLAG_SCANNING) {
474 /* Flash scanning is in progress. Don't muck about with the block 474 /* Flash scanning is in progress. Don't muck about with the block
@@ -649,164 +649,6 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
649 up(&c->erase_free_sem); 649 up(&c->erase_free_sem);
650} 650}
651 651
652#if CONFIG_JFFS2_FS_DEBUG >= 2
653void jffs2_dump_block_lists(struct jffs2_sb_info *c)
654{
655
656
657 printk(KERN_DEBUG "jffs2_dump_block_lists:\n");
658 printk(KERN_DEBUG "flash_size: %08x\n", c->flash_size);
659 printk(KERN_DEBUG "used_size: %08x\n", c->used_size);
660 printk(KERN_DEBUG "dirty_size: %08x\n", c->dirty_size);
661 printk(KERN_DEBUG "wasted_size: %08x\n", c->wasted_size);
662 printk(KERN_DEBUG "unchecked_size: %08x\n", c->unchecked_size);
663 printk(KERN_DEBUG "free_size: %08x\n", c->free_size);
664 printk(KERN_DEBUG "erasing_size: %08x\n", c->erasing_size);
665 printk(KERN_DEBUG "bad_size: %08x\n", c->bad_size);
666 printk(KERN_DEBUG "sector_size: %08x\n", c->sector_size);
667 printk(KERN_DEBUG "jffs2_reserved_blocks size: %08x\n",c->sector_size * c->resv_blocks_write);
668
669 if (c->nextblock) {
670 printk(KERN_DEBUG "nextblock: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
671 c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->unchecked_size, c->nextblock->free_size);
672 } else {
673 printk(KERN_DEBUG "nextblock: NULL\n");
674 }
675 if (c->gcblock) {
676 printk(KERN_DEBUG "gcblock: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
677 c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size, c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
678 } else {
679 printk(KERN_DEBUG "gcblock: NULL\n");
680 }
681 if (list_empty(&c->clean_list)) {
682 printk(KERN_DEBUG "clean_list: empty\n");
683 } else {
684 struct list_head *this;
685 int numblocks = 0;
686 uint32_t dirty = 0;
687
688 list_for_each(this, &c->clean_list) {
689 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
690 numblocks ++;
691 dirty += jeb->wasted_size;
692 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);
693 }
694 printk (KERN_DEBUG "Contains %d blocks with total wasted size %u, average wasted size: %u\n", numblocks, dirty, dirty / numblocks);
695 }
696 if (list_empty(&c->very_dirty_list)) {
697 printk(KERN_DEBUG "very_dirty_list: empty\n");
698 } else {
699 struct list_head *this;
700 int numblocks = 0;
701 uint32_t dirty = 0;
702
703 list_for_each(this, &c->very_dirty_list) {
704 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
705 numblocks ++;
706 dirty += jeb->dirty_size;
707 printk(KERN_DEBUG "very_dirty_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
708 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
709 }
710 printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
711 numblocks, dirty, dirty / numblocks);
712 }
713 if (list_empty(&c->dirty_list)) {
714 printk(KERN_DEBUG "dirty_list: empty\n");
715 } else {
716 struct list_head *this;
717 int numblocks = 0;
718 uint32_t dirty = 0;
719
720 list_for_each(this, &c->dirty_list) {
721 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
722 numblocks ++;
723 dirty += jeb->dirty_size;
724 printk(KERN_DEBUG "dirty_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
725 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
726 }
727 printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
728 numblocks, dirty, dirty / numblocks);
729 }
730 if (list_empty(&c->erasable_list)) {
731 printk(KERN_DEBUG "erasable_list: empty\n");
732 } else {
733 struct list_head *this;
734
735 list_for_each(this, &c->erasable_list) {
736 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
737 printk(KERN_DEBUG "erasable_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
738 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
739 }
740 }
741 if (list_empty(&c->erasing_list)) {
742 printk(KERN_DEBUG "erasing_list: empty\n");
743 } else {
744 struct list_head *this;
745
746 list_for_each(this, &c->erasing_list) {
747 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
748 printk(KERN_DEBUG "erasing_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
749 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
750 }
751 }
752 if (list_empty(&c->erase_pending_list)) {
753 printk(KERN_DEBUG "erase_pending_list: empty\n");
754 } else {
755 struct list_head *this;
756
757 list_for_each(this, &c->erase_pending_list) {
758 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
759 printk(KERN_DEBUG "erase_pending_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
760 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
761 }
762 }
763 if (list_empty(&c->erasable_pending_wbuf_list)) {
764 printk(KERN_DEBUG "erasable_pending_wbuf_list: empty\n");
765 } else {
766 struct list_head *this;
767
768 list_for_each(this, &c->erasable_pending_wbuf_list) {
769 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
770 printk(KERN_DEBUG "erasable_pending_wbuf_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
771 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
772 }
773 }
774 if (list_empty(&c->free_list)) {
775 printk(KERN_DEBUG "free_list: empty\n");
776 } else {
777 struct list_head *this;
778
779 list_for_each(this, &c->free_list) {
780 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
781 printk(KERN_DEBUG "free_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
782 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
783 }
784 }
785 if (list_empty(&c->bad_list)) {
786 printk(KERN_DEBUG "bad_list: empty\n");
787 } else {
788 struct list_head *this;
789
790 list_for_each(this, &c->bad_list) {
791 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
792 printk(KERN_DEBUG "bad_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
793 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
794 }
795 }
796 if (list_empty(&c->bad_used_list)) {
797 printk(KERN_DEBUG "bad_used_list: empty\n");
798 } else {
799 struct list_head *this;
800
801 list_for_each(this, &c->bad_used_list) {
802 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
803 printk(KERN_DEBUG "bad_used_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
804 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
805 }
806 }
807}
808#endif /* CONFIG_JFFS2_FS_DEBUG */
809
810int jffs2_thread_should_wake(struct jffs2_sb_info *c) 652int jffs2_thread_should_wake(struct jffs2_sb_info *c)
811{ 653{
812 int ret = 0; 654 int ret = 0;
diff --git a/fs/jffs2/read.c b/fs/jffs2/read.c
index c7f9068907cf..9706534786ec 100644
--- a/fs/jffs2/read.c
+++ b/fs/jffs2/read.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: read.c,v 1.39 2005/03/01 10:34:03 dedekind Exp $ 10 * $Id: read.c,v 1.40 2005/07/17 06:56:21 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -174,7 +174,7 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
174 if (frag) { 174 if (frag) {
175 D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset)); 175 D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset));
176 holesize = min(holesize, frag->ofs - offset); 176 holesize = min(holesize, frag->ofs - offset);
177 D2(jffs2_print_frag_list(f)); 177 D2(jffs2_dbg_dump_fragtree(f));
178 } 178 }
179 D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize)); 179 D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize));
180 memset(buf, 0, holesize); 180 memset(buf, 0, holesize);
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 5b2a83599d73..cf39bcf3e3cf 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: readinode.c,v 1.125 2005/07/10 13:13:55 dedekind Exp $ 10 * $Id: readinode.c,v 1.126 2005/07/17 06:56:21 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -22,104 +22,6 @@
22 22
23static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag); 23static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag);
24 24
25#if CONFIG_JFFS2_FS_DEBUG >= 2
26static void jffs2_print_fragtree(struct rb_root *list, int permitbug)
27{
28 struct jffs2_node_frag *this = frag_first(list);
29 uint32_t lastofs = 0;
30 int buggy = 0;
31
32 while(this) {
33 if (this->node)
34 printk(KERN_DEBUG "frag %04x-%04x: 0x%08x(%d) on flash (*%p). left (%p), right (%p), parent (%p)\n",
35 this->ofs, this->ofs+this->size, ref_offset(this->node->raw), ref_flags(this->node->raw),
36 this, frag_left(this), frag_right(this), frag_parent(this));
37 else
38 printk(KERN_DEBUG "frag %04x-%04x: hole (*%p). left (%p} right (%p), parent (%p)\n", this->ofs,
39 this->ofs+this->size, this, frag_left(this), frag_right(this), frag_parent(this));
40 if (this->ofs != lastofs)
41 buggy = 1;
42 lastofs = this->ofs+this->size;
43 this = frag_next(this);
44 }
45 if (buggy && !permitbug) {
46 printk(KERN_CRIT "Frag tree got a hole in it\n");
47 BUG();
48 }
49}
50
51void jffs2_print_frag_list(struct jffs2_inode_info *f)
52{
53 jffs2_print_fragtree(&f->fragtree, 0);
54
55 if (f->metadata) {
56 printk(KERN_DEBUG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
57 }
58}
59#endif
60
61#if CONFIG_JFFS2_FS_DEBUG >= 1
62static int jffs2_sanitycheck_fragtree(struct jffs2_inode_info *f)
63{
64 struct jffs2_node_frag *frag;
65 int bitched = 0;
66
67 for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
68
69 struct jffs2_full_dnode *fn = frag->node;
70 if (!fn || !fn->raw)
71 continue;
72
73 if (ref_flags(fn->raw) == REF_PRISTINE) {
74
75 if (fn->frags > 1) {
76 printk(KERN_WARNING "REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2\n", ref_offset(fn->raw), fn->frags);
77 bitched = 1;
78 }
79 /* A hole node which isn't multi-page should be garbage-collected
80 and merged anyway, so we just check for the frag size here,
81 rather than mucking around with actually reading the node
82 and checking the compression type, which is the real way
83 to tell a hole node. */
84 if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag) && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) {
85 printk(KERN_WARNING "REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2\n",
86 ref_offset(fn->raw));
87 bitched = 1;
88 }
89
90 if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag) && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) {
91 printk(KERN_WARNING "REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2\n",
92 ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size);
93 bitched = 1;
94 }
95 }
96 }
97
98 if (bitched) {
99 struct jffs2_node_frag *thisfrag;
100
101 printk(KERN_WARNING "Inode is #%u\n", f->inocache->ino);
102 thisfrag = frag_first(&f->fragtree);
103 while (thisfrag) {
104 if (!thisfrag->node) {
105 printk("Frag @0x%x-0x%x; node-less hole\n",
106 thisfrag->ofs, thisfrag->size + thisfrag->ofs);
107 } else if (!thisfrag->node->raw) {
108 printk("Frag @0x%x-0x%x; raw-less hole\n",
109 thisfrag->ofs, thisfrag->size + thisfrag->ofs);
110 } else {
111 printk("Frag @0x%x-0x%x; raw at 0x%08x(%d) (0x%x-0x%x)\n",
112 thisfrag->ofs, thisfrag->size + thisfrag->ofs,
113 ref_offset(thisfrag->node->raw), ref_flags(thisfrag->node->raw),
114 thisfrag->node->ofs, thisfrag->node->ofs+thisfrag->node->size);
115 }
116 thisfrag = frag_next(thisfrag);
117 }
118 }
119 return bitched;
120}
121#endif /* D1 */
122
123static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this) 25static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this)
124{ 26{
125 if (this->node) { 27 if (this->node) {
@@ -190,12 +92,8 @@ int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_in
190 mark_ref_normal(next->node->raw); 92 mark_ref_normal(next->node->raw);
191 } 93 }
192 } 94 }
193 D2(if (jffs2_sanitycheck_fragtree(f)) { 95 D2(jffs2_dbg_fragtree_paranoia_check(f));
194 printk(KERN_WARNING "Just added node %04x-%04x @0x%08x on flash, newfrag *%p\n", 96 D2(jffs2_dbg_dump_fragtree(f));
195 fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag);
196 return 0;
197 })
198 D2(jffs2_print_frag_list(f));
199 return 0; 97 return 0;
200} 98}
201 99
@@ -582,7 +480,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
582 480
583 jffs2_free_tmp_dnode_info(tn); 481 jffs2_free_tmp_dnode_info(tn);
584 } 482 }
585 D1(jffs2_sanitycheck_fragtree(f)); 483 jffs2_dbg_fragtree_paranoia_check(f);
586 484
587 if (!fn) { 485 if (!fn) {
588 /* No data nodes for this inode. */ 486 /* No data nodes for this inode. */
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index b63160f83bab..a2a51b7c2fd9 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: scan.c,v 1.119 2005/02/17 17:51:13 dedekind Exp $ 10 * $Id: scan.c,v 1.120 2005/07/17 06:56:21 dedekind Exp $
11 * 11 *
12 */ 12 */
13#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -130,7 +130,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
130 if (ret < 0) 130 if (ret < 0)
131 goto out; 131 goto out;
132 132
133 ACCT_PARANOIA_CHECK(jeb); 133 jffs2_dbg_acct_paranoia_check(c, jeb);
134 134
135 /* Now decide which list to put it on */ 135 /* Now decide which list to put it on */
136 switch(ret) { 136 switch(ret) {
@@ -370,7 +370,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
370scan_more: 370scan_more:
371 while(ofs < jeb->offset + c->sector_size) { 371 while(ofs < jeb->offset + c->sector_size) {
372 372
373 D1(ACCT_PARANOIA_CHECK(jeb)); 373 jffs2_dbg_acct_paranoia_check(c, jeb);
374 374
375 cond_resched(); 375 cond_resched();
376 376
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 316133c626b7..85ae51d2060a 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -9,7 +9,7 @@
9 * 9 *
10 * For licensing information, see the file 'LICENCE' in this directory. 10 * For licensing information, see the file 'LICENCE' in this directory.
11 * 11 *
12 * $Id: wbuf.c,v 1.92 2005/04/05 12:51:54 dedekind Exp $ 12 * $Id: wbuf.c,v 1.93 2005/07/17 06:56:21 dedekind Exp $
13 * 13 *
14 */ 14 */
15 15
@@ -139,7 +139,7 @@ static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock
139{ 139{
140 D1(printk("About to refile bad block at %08x\n", jeb->offset)); 140 D1(printk("About to refile bad block at %08x\n", jeb->offset));
141 141
142 D2(jffs2_dump_block_lists(c)); 142 D2(jffs2_dbg_dump_block_lists(c));
143 /* File the existing block on the bad_used_list.... */ 143 /* File the existing block on the bad_used_list.... */
144 if (c->nextblock == jeb) 144 if (c->nextblock == jeb)
145 c->nextblock = NULL; 145 c->nextblock = NULL;
@@ -156,7 +156,7 @@ static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock
156 c->nr_erasing_blocks++; 156 c->nr_erasing_blocks++;
157 jffs2_erase_pending_trigger(c); 157 jffs2_erase_pending_trigger(c);
158 } 158 }
159 D2(jffs2_dump_block_lists(c)); 159 D2(jffs2_dbg_dump_block_lists(c));
160 160
161 /* Adjust its size counts accordingly */ 161 /* Adjust its size counts accordingly */
162 c->wasted_size += jeb->free_size; 162 c->wasted_size += jeb->free_size;
@@ -164,8 +164,8 @@ static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock
164 jeb->wasted_size += jeb->free_size; 164 jeb->wasted_size += jeb->free_size;
165 jeb->free_size = 0; 165 jeb->free_size = 0;
166 166
167 ACCT_SANITY_CHECK(c,jeb); 167 jffs2_dbg_acct_sanity_check(c,jeb);
168 D1(ACCT_PARANOIA_CHECK(jeb)); 168 jffs2_dbg_acct_paranoia_check(c, jeb);
169} 169}
170 170
171/* Recover from failure to write wbuf. Recover the nodes up to the 171/* Recover from failure to write wbuf. Recover the nodes up to the
@@ -392,11 +392,11 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
392 else 392 else
393 jeb->last_node = container_of(first_raw, struct jffs2_raw_node_ref, next_phys); 393 jeb->last_node = container_of(first_raw, struct jffs2_raw_node_ref, next_phys);
394 394
395 ACCT_SANITY_CHECK(c,jeb); 395 jffs2_dbg_acct_sanity_check(c,jeb);
396 D1(ACCT_PARANOIA_CHECK(jeb)); 396 jffs2_dbg_acct_paranoia_check(c, jeb);
397 397
398 ACCT_SANITY_CHECK(c,new_jeb); 398 jffs2_dbg_acct_sanity_check(c,new_jeb);
399 D1(ACCT_PARANOIA_CHECK(new_jeb)); 399 jffs2_dbg_acct_paranoia_check(c, new_jeb);
400 400
401 spin_unlock(&c->erase_completion_lock); 401 spin_unlock(&c->erase_completion_lock);
402 402
@@ -973,7 +973,7 @@ int jffs2_check_oob_empty( struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb
973 973
974 if (buf[i] != 0xFF) { 974 if (buf[i] != 0xFF) {
975 D2(printk(KERN_DEBUG "Found %02x at %x in OOB for %08x\n", 975 D2(printk(KERN_DEBUG "Found %02x at %x in OOB for %08x\n",
976 buf[page+i], page+i, jeb->offset)); 976 buf[i], i, jeb->offset));
977 ret = 1; 977 ret = 1;
978 goto out; 978 goto out;
979 } 979 }
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index 69100615d9ae..b6a53e5aaa00 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: write.c,v 1.92 2005/04/13 13:22:35 dwmw2 Exp $ 10 * $Id: write.c,v 1.93 2005/07/17 06:56:21 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -54,34 +54,6 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint
54 return 0; 54 return 0;
55} 55}
56 56
57#if CONFIG_JFFS2_FS_DEBUG > 0
58static void writecheck(struct jffs2_sb_info *c, uint32_t ofs)
59{
60 unsigned char buf[16];
61 size_t retlen;
62 int ret, i;
63
64 ret = jffs2_flash_read(c, ofs, 16, &retlen, buf);
65 if (ret || (retlen != 16)) {
66 D1(printk(KERN_DEBUG "read failed or short in writecheck(). ret %d, retlen %zd\n", ret, retlen));
67 return;
68 }
69 ret = 0;
70 for (i=0; i<16; i++) {
71 if (buf[i] != 0xff)
72 ret = 1;
73 }
74 if (ret) {
75 printk(KERN_WARNING "ARGH. About to write node to 0x%08x on flash, but there are data already there:\n", ofs);
76 printk(KERN_WARNING "0x%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
77 ofs,
78 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
79 buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
80 }
81}
82#endif
83
84
85/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it, 57/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it,
86 write it to the flash, link it into the existing inode/fragment list */ 58 write it to the flash, link it into the existing inode/fragment list */
87 59
@@ -106,7 +78,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
106 vecs[1].iov_base = (unsigned char *)data; 78 vecs[1].iov_base = (unsigned char *)data;
107 vecs[1].iov_len = datalen; 79 vecs[1].iov_len = datalen;
108 80
109 D1(writecheck(c, flash_ofs)); 81 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
110 82
111 if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) { 83 if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) {
112 printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen); 84 printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen);
@@ -177,8 +149,8 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
177 149
178 D1(printk(KERN_DEBUG "Retrying failed write.\n")); 150 D1(printk(KERN_DEBUG "Retrying failed write.\n"));
179 151
180 ACCT_SANITY_CHECK(c,jeb); 152 jffs2_dbg_acct_sanity_check(c,jeb);
181 D1(ACCT_PARANOIA_CHECK(jeb)); 153 jffs2_dbg_acct_paranoia_check(c, jeb);
182 154
183 if (alloc_mode == ALLOC_GC) { 155 if (alloc_mode == ALLOC_GC) {
184 ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, &dummy); 156 ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, &dummy);
@@ -194,8 +166,8 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
194 if (!ret) { 166 if (!ret) {
195 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); 167 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
196 168
197 ACCT_SANITY_CHECK(c,jeb); 169 jffs2_dbg_acct_sanity_check(c,jeb);
198 D1(ACCT_PARANOIA_CHECK(jeb)); 170 jffs2_dbg_acct_paranoia_check(c, jeb);
199 171
200 goto retry; 172 goto retry;
201 } 173 }
@@ -232,7 +204,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
232 je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen))); 204 je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen)));
233 205
234 if (retried) { 206 if (retried) {
235 ACCT_SANITY_CHECK(c,NULL); 207 jffs2_dbg_acct_sanity_check(c,NULL);
236 } 208 }
237 209
238 return fn; 210 return fn;
@@ -250,7 +222,8 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
250 D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n", 222 D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n",
251 je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino), 223 je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino),
252 je32_to_cpu(rd->name_crc))); 224 je32_to_cpu(rd->name_crc)));
253 D1(writecheck(c, flash_ofs)); 225
226 jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len);
254 227
255 D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) { 228 D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) {
256 printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n"); 229 printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n");
@@ -322,8 +295,8 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
322 295
323 D1(printk(KERN_DEBUG "Retrying failed write.\n")); 296 D1(printk(KERN_DEBUG "Retrying failed write.\n"));
324 297
325 ACCT_SANITY_CHECK(c,jeb); 298 jffs2_dbg_acct_sanity_check(c,jeb);
326 D1(ACCT_PARANOIA_CHECK(jeb)); 299 jffs2_dbg_acct_paranoia_check(c, jeb);
327 300
328 if (alloc_mode == ALLOC_GC) { 301 if (alloc_mode == ALLOC_GC) {
329 ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, &dummy); 302 ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, &dummy);
@@ -338,8 +311,8 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
338 311
339 if (!ret) { 312 if (!ret) {
340 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); 313 D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
341 ACCT_SANITY_CHECK(c,jeb); 314 jffs2_dbg_acct_sanity_check(c,jeb);
342 D1(ACCT_PARANOIA_CHECK(jeb)); 315 jffs2_dbg_acct_paranoia_check(c, jeb);
343 goto retry; 316 goto retry;
344 } 317 }
345 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); 318 D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
@@ -359,7 +332,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
359 spin_unlock(&c->erase_completion_lock); 332 spin_unlock(&c->erase_completion_lock);
360 333
361 if (retried) { 334 if (retried) {
362 ACCT_SANITY_CHECK(c,NULL); 335 jffs2_dbg_acct_sanity_check(c,NULL);
363 } 336 }
364 337
365 return fd; 338 return fd;