Loading...
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright © 2001-2007 Red Hat, Inc.
5 * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
6 *
7 * Created by David Woodhouse <dwmw2@infradead.org>
8 *
9 * For licensing information, see the file 'LICENCE' in this directory.
10 *
11 */
12
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
15#include <linux/kernel.h>
16#include <linux/types.h>
17#include <linux/pagemap.h>
18#include <linux/crc32.h>
19#include <linux/jffs2.h>
20#include <linux/mtd/mtd.h>
21#include <linux/slab.h>
22#include "nodelist.h"
23#include "debug.h"
24
25#ifdef JFFS2_DBG_SANITY_CHECKS
26
27void
28__jffs2_dbg_acct_sanity_check_nolock(struct jffs2_sb_info *c,
29 struct jffs2_eraseblock *jeb)
30{
31 if (unlikely(jeb && jeb->used_size + jeb->dirty_size +
32 jeb->free_size + jeb->wasted_size +
33 jeb->unchecked_size != c->sector_size)) {
34 JFFS2_ERROR("eeep, space accounting for block at 0x%08x is screwed.\n", jeb->offset);
35 JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
36 jeb->free_size, jeb->dirty_size, jeb->used_size,
37 jeb->wasted_size, jeb->unchecked_size, c->sector_size);
38 BUG();
39 }
40
41 if (unlikely(c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size
42 + c->wasted_size + c->unchecked_size != c->flash_size)) {
43 JFFS2_ERROR("eeep, space accounting superblock info is screwed.\n");
44 JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + erasing %#08x + bad %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
45 c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size,
46 c->wasted_size, c->unchecked_size, c->flash_size);
47 BUG();
48 }
49}
50
51void
52__jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c,
53 struct jffs2_eraseblock *jeb)
54{
55 spin_lock(&c->erase_completion_lock);
56 jffs2_dbg_acct_sanity_check_nolock(c, jeb);
57 spin_unlock(&c->erase_completion_lock);
58}
59
60#endif /* JFFS2_DBG_SANITY_CHECKS */
61
62#ifdef JFFS2_DBG_PARANOIA_CHECKS
63/*
64 * Check the fragtree.
65 */
66void
67__jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f)
68{
69 mutex_lock(&f->sem);
70 __jffs2_dbg_fragtree_paranoia_check_nolock(f);
71 mutex_unlock(&f->sem);
72}
73
74void
75__jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f)
76{
77 struct jffs2_node_frag *frag;
78 int bitched = 0;
79
80 for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
81 struct jffs2_full_dnode *fn = frag->node;
82
83 if (!fn || !fn->raw)
84 continue;
85
86 if (ref_flags(fn->raw) == REF_PRISTINE) {
87 if (fn->frags > 1) {
88 JFFS2_ERROR("REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2.\n",
89 ref_offset(fn->raw), fn->frags);
90 bitched = 1;
91 }
92
93 /* A hole node which isn't multi-page should be garbage-collected
94 and merged anyway, so we just check for the frag size here,
95 rather than mucking around with actually reading the node
96 and checking the compression type, which is the real way
97 to tell a hole node. */
98 if (frag->ofs & (PAGE_SIZE-1) && frag_prev(frag)
99 && frag_prev(frag)->size < PAGE_SIZE && frag_prev(frag)->node) {
100 JFFS2_ERROR("REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2.\n",
101 ref_offset(fn->raw));
102 bitched = 1;
103 }
104
105 if ((frag->ofs+frag->size) & (PAGE_SIZE-1) && frag_next(frag)
106 && frag_next(frag)->size < PAGE_SIZE && frag_next(frag)->node) {
107 JFFS2_ERROR("REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2.\n",
108 ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size);
109 bitched = 1;
110 }
111 }
112 }
113
114 if (bitched) {
115 JFFS2_ERROR("fragtree is corrupted.\n");
116 __jffs2_dbg_dump_fragtree_nolock(f);
117 BUG();
118 }
119}
120
121/*
122 * Check if the flash contains all 0xFF before we start writing.
123 */
124void
125__jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
126 uint32_t ofs, int len)
127{
128 size_t retlen;
129 int ret, i;
130 unsigned char *buf;
131
132 buf = kmalloc(len, GFP_KERNEL);
133 if (!buf)
134 return;
135
136 ret = jffs2_flash_read(c, ofs, len, &retlen, buf);
137 if (ret || (retlen != len)) {
138 JFFS2_WARNING("read %d bytes failed or short. ret %d, retlen %zd.\n",
139 len, ret, retlen);
140 kfree(buf);
141 return;
142 }
143
144 ret = 0;
145 for (i = 0; i < len; i++)
146 if (buf[i] != 0xff)
147 ret = 1;
148
149 if (ret) {
150 JFFS2_ERROR("argh, about to write node to %#08x on flash, but there are data already there. The first corrupted byte is at %#08x offset.\n",
151 ofs, ofs + i);
152 __jffs2_dbg_dump_buffer(buf, len, ofs);
153 kfree(buf);
154 BUG();
155 }
156
157 kfree(buf);
158}
159
160static void __jffs2_dbg_superblock_counts(struct jffs2_sb_info *c)
161{
162 struct jffs2_eraseblock *jeb;
163 uint32_t free = 0, dirty = 0, used = 0, wasted = 0,
164 erasing = 0, bad = 0, unchecked = 0;
165 int nr_counted = 0;
166 int dump = 0;
167
168 if (c->gcblock) {
169 nr_counted++;
170 free += c->gcblock->free_size;
171 dirty += c->gcblock->dirty_size;
172 used += c->gcblock->used_size;
173 wasted += c->gcblock->wasted_size;
174 unchecked += c->gcblock->unchecked_size;
175 }
176 if (c->nextblock) {
177 nr_counted++;
178 free += c->nextblock->free_size;
179 dirty += c->nextblock->dirty_size;
180 used += c->nextblock->used_size;
181 wasted += c->nextblock->wasted_size;
182 unchecked += c->nextblock->unchecked_size;
183 }
184 list_for_each_entry(jeb, &c->clean_list, list) {
185 nr_counted++;
186 free += jeb->free_size;
187 dirty += jeb->dirty_size;
188 used += jeb->used_size;
189 wasted += jeb->wasted_size;
190 unchecked += jeb->unchecked_size;
191 }
192 list_for_each_entry(jeb, &c->very_dirty_list, list) {
193 nr_counted++;
194 free += jeb->free_size;
195 dirty += jeb->dirty_size;
196 used += jeb->used_size;
197 wasted += jeb->wasted_size;
198 unchecked += jeb->unchecked_size;
199 }
200 list_for_each_entry(jeb, &c->dirty_list, list) {
201 nr_counted++;
202 free += jeb->free_size;
203 dirty += jeb->dirty_size;
204 used += jeb->used_size;
205 wasted += jeb->wasted_size;
206 unchecked += jeb->unchecked_size;
207 }
208 list_for_each_entry(jeb, &c->erasable_list, list) {
209 nr_counted++;
210 free += jeb->free_size;
211 dirty += jeb->dirty_size;
212 used += jeb->used_size;
213 wasted += jeb->wasted_size;
214 unchecked += jeb->unchecked_size;
215 }
216 list_for_each_entry(jeb, &c->erasable_pending_wbuf_list, list) {
217 nr_counted++;
218 free += jeb->free_size;
219 dirty += jeb->dirty_size;
220 used += jeb->used_size;
221 wasted += jeb->wasted_size;
222 unchecked += jeb->unchecked_size;
223 }
224 list_for_each_entry(jeb, &c->erase_pending_list, list) {
225 nr_counted++;
226 free += jeb->free_size;
227 dirty += jeb->dirty_size;
228 used += jeb->used_size;
229 wasted += jeb->wasted_size;
230 unchecked += jeb->unchecked_size;
231 }
232 list_for_each_entry(jeb, &c->free_list, list) {
233 nr_counted++;
234 free += jeb->free_size;
235 dirty += jeb->dirty_size;
236 used += jeb->used_size;
237 wasted += jeb->wasted_size;
238 unchecked += jeb->unchecked_size;
239 }
240 list_for_each_entry(jeb, &c->bad_used_list, list) {
241 nr_counted++;
242 free += jeb->free_size;
243 dirty += jeb->dirty_size;
244 used += jeb->used_size;
245 wasted += jeb->wasted_size;
246 unchecked += jeb->unchecked_size;
247 }
248
249 list_for_each_entry(jeb, &c->erasing_list, list) {
250 nr_counted++;
251 erasing += c->sector_size;
252 }
253 list_for_each_entry(jeb, &c->erase_checking_list, list) {
254 nr_counted++;
255 erasing += c->sector_size;
256 }
257 list_for_each_entry(jeb, &c->erase_complete_list, list) {
258 nr_counted++;
259 erasing += c->sector_size;
260 }
261 list_for_each_entry(jeb, &c->bad_list, list) {
262 nr_counted++;
263 bad += c->sector_size;
264 }
265
266#define check(sz) \
267do { \
268 if (sz != c->sz##_size) { \
269 pr_warn("%s_size mismatch counted 0x%x, c->%s_size 0x%x\n", \
270 #sz, sz, #sz, c->sz##_size); \
271 dump = 1; \
272 } \
273} while (0)
274
275 check(free);
276 check(dirty);
277 check(used);
278 check(wasted);
279 check(unchecked);
280 check(bad);
281 check(erasing);
282
283#undef check
284
285 if (nr_counted != c->nr_blocks) {
286 pr_warn("%s counted only 0x%x blocks of 0x%x. Where are the others?\n",
287 __func__, nr_counted, c->nr_blocks);
288 dump = 1;
289 }
290
291 if (dump) {
292 __jffs2_dbg_dump_block_lists_nolock(c);
293 BUG();
294 }
295}
296
297/*
298 * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
299 */
300void
301__jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c,
302 struct jffs2_eraseblock *jeb)
303{
304 spin_lock(&c->erase_completion_lock);
305 __jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
306 spin_unlock(&c->erase_completion_lock);
307}
308
309void
310__jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
311 struct jffs2_eraseblock *jeb)
312{
313 uint32_t my_used_size = 0;
314 uint32_t my_unchecked_size = 0;
315 uint32_t my_dirty_size = 0;
316 struct jffs2_raw_node_ref *ref2 = jeb->first_node;
317
318 while (ref2) {
319 uint32_t totlen = ref_totlen(c, jeb, ref2);
320
321 if (ref_offset(ref2) < jeb->offset ||
322 ref_offset(ref2) > jeb->offset + c->sector_size) {
323 JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.\n",
324 ref_offset(ref2), jeb->offset);
325 goto error;
326
327 }
328 if (ref_flags(ref2) == REF_UNCHECKED)
329 my_unchecked_size += totlen;
330 else if (!ref_obsolete(ref2))
331 my_used_size += totlen;
332 else
333 my_dirty_size += totlen;
334
335 if ((!ref_next(ref2)) != (ref2 == jeb->last_node)) {
336 JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next at %#08x (mem %p), last_node is at %#08x (mem %p).\n",
337 ref_offset(ref2), ref2, ref_offset(ref_next(ref2)), ref_next(ref2),
338 ref_offset(jeb->last_node), jeb->last_node);
339 goto error;
340 }
341 ref2 = ref_next(ref2);
342 }
343
344 if (my_used_size != jeb->used_size) {
345 JFFS2_ERROR("Calculated used size %#08x != stored used size %#08x.\n",
346 my_used_size, jeb->used_size);
347 goto error;
348 }
349
350 if (my_unchecked_size != jeb->unchecked_size) {
351 JFFS2_ERROR("Calculated unchecked size %#08x != stored unchecked size %#08x.\n",
352 my_unchecked_size, jeb->unchecked_size);
353 goto error;
354 }
355
356#if 0
357 /* This should work when we implement ref->__totlen elemination */
358 if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) {
359 JFFS2_ERROR("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n",
360 my_dirty_size, jeb->dirty_size + jeb->wasted_size);
361 goto error;
362 }
363
364 if (jeb->free_size == 0
365 && my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) {
366 JFFS2_ERROR("The sum of all nodes in block (%#x) != size of block (%#x)\n",
367 my_used_size + my_unchecked_size + my_dirty_size,
368 c->sector_size);
369 goto error;
370 }
371#endif
372
373 if (!(c->flags & (JFFS2_SB_FLAG_BUILDING|JFFS2_SB_FLAG_SCANNING)))
374 __jffs2_dbg_superblock_counts(c);
375
376 return;
377
378error:
379 __jffs2_dbg_dump_node_refs_nolock(c, jeb);
380 __jffs2_dbg_dump_jeb_nolock(jeb);
381 __jffs2_dbg_dump_block_lists_nolock(c);
382 BUG();
383
384}
385#endif /* JFFS2_DBG_PARANOIA_CHECKS */
386
387#if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS)
388/*
389 * Dump the node_refs of the 'jeb' JFFS2 eraseblock.
390 */
391void
392__jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c,
393 struct jffs2_eraseblock *jeb)
394{
395 spin_lock(&c->erase_completion_lock);
396 __jffs2_dbg_dump_node_refs_nolock(c, jeb);
397 spin_unlock(&c->erase_completion_lock);
398}
399
400void
401__jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c,
402 struct jffs2_eraseblock *jeb)
403{
404 struct jffs2_raw_node_ref *ref;
405 int i = 0;
406
407 printk(JFFS2_DBG_MSG_PREFIX " Dump node_refs of the eraseblock %#08x\n", jeb->offset);
408 if (!jeb->first_node) {
409 printk(JFFS2_DBG_MSG_PREFIX " no nodes in the eraseblock %#08x\n", jeb->offset);
410 return;
411 }
412
413 printk(JFFS2_DBG);
414 for (ref = jeb->first_node; ; ref = ref_next(ref)) {
415 printk("%#08x", ref_offset(ref));
416#ifdef TEST_TOTLEN
417 printk("(%x)", ref->__totlen);
418#endif
419 if (ref_next(ref))
420 printk("->");
421 else
422 break;
423 if (++i == 4) {
424 i = 0;
425 printk("\n" JFFS2_DBG);
426 }
427 }
428 printk("\n");
429}
430
431/*
432 * Dump an eraseblock's space accounting.
433 */
434void
435__jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
436{
437 spin_lock(&c->erase_completion_lock);
438 __jffs2_dbg_dump_jeb_nolock(jeb);
439 spin_unlock(&c->erase_completion_lock);
440}
441
442void
443__jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb)
444{
445 if (!jeb)
446 return;
447
448 printk(JFFS2_DBG_MSG_PREFIX " dump space accounting for the eraseblock at %#08x:\n",
449 jeb->offset);
450
451 printk(JFFS2_DBG "used_size: %#08x\n", jeb->used_size);
452 printk(JFFS2_DBG "dirty_size: %#08x\n", jeb->dirty_size);
453 printk(JFFS2_DBG "wasted_size: %#08x\n", jeb->wasted_size);
454 printk(JFFS2_DBG "unchecked_size: %#08x\n", jeb->unchecked_size);
455 printk(JFFS2_DBG "free_size: %#08x\n", jeb->free_size);
456}
457
458void
459__jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c)
460{
461 spin_lock(&c->erase_completion_lock);
462 __jffs2_dbg_dump_block_lists_nolock(c);
463 spin_unlock(&c->erase_completion_lock);
464}
465
466void
467__jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c)
468{
469 printk(JFFS2_DBG_MSG_PREFIX " dump JFFS2 blocks lists:\n");
470
471 printk(JFFS2_DBG "flash_size: %#08x\n", c->flash_size);
472 printk(JFFS2_DBG "used_size: %#08x\n", c->used_size);
473 printk(JFFS2_DBG "dirty_size: %#08x\n", c->dirty_size);
474 printk(JFFS2_DBG "wasted_size: %#08x\n", c->wasted_size);
475 printk(JFFS2_DBG "unchecked_size: %#08x\n", c->unchecked_size);
476 printk(JFFS2_DBG "free_size: %#08x\n", c->free_size);
477 printk(JFFS2_DBG "erasing_size: %#08x\n", c->erasing_size);
478 printk(JFFS2_DBG "bad_size: %#08x\n", c->bad_size);
479 printk(JFFS2_DBG "sector_size: %#08x\n", c->sector_size);
480 printk(JFFS2_DBG "jffs2_reserved_blocks size: %#08x\n",
481 c->sector_size * c->resv_blocks_write);
482
483 if (c->nextblock)
484 printk(JFFS2_DBG "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
485 c->nextblock->offset, c->nextblock->used_size,
486 c->nextblock->dirty_size, c->nextblock->wasted_size,
487 c->nextblock->unchecked_size, c->nextblock->free_size);
488 else
489 printk(JFFS2_DBG "nextblock: NULL\n");
490
491 if (c->gcblock)
492 printk(JFFS2_DBG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
493 c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size,
494 c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
495 else
496 printk(JFFS2_DBG "gcblock: NULL\n");
497
498 if (list_empty(&c->clean_list)) {
499 printk(JFFS2_DBG "clean_list: empty\n");
500 } else {
501 struct list_head *this;
502 int numblocks = 0;
503 uint32_t dirty = 0;
504
505 list_for_each(this, &c->clean_list) {
506 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
507 numblocks ++;
508 dirty += jeb->wasted_size;
509 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
510 printk(JFFS2_DBG "clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
511 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
512 jeb->unchecked_size, jeb->free_size);
513 }
514 }
515
516 printk (JFFS2_DBG "Contains %d blocks with total wasted size %u, average wasted size: %u\n",
517 numblocks, dirty, dirty / numblocks);
518 }
519
520 if (list_empty(&c->very_dirty_list)) {
521 printk(JFFS2_DBG "very_dirty_list: empty\n");
522 } else {
523 struct list_head *this;
524 int numblocks = 0;
525 uint32_t dirty = 0;
526
527 list_for_each(this, &c->very_dirty_list) {
528 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
529
530 numblocks ++;
531 dirty += jeb->dirty_size;
532 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
533 printk(JFFS2_DBG "very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
534 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
535 jeb->unchecked_size, jeb->free_size);
536 }
537 }
538
539 printk (JFFS2_DBG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
540 numblocks, dirty, dirty / numblocks);
541 }
542
543 if (list_empty(&c->dirty_list)) {
544 printk(JFFS2_DBG "dirty_list: empty\n");
545 } else {
546 struct list_head *this;
547 int numblocks = 0;
548 uint32_t dirty = 0;
549
550 list_for_each(this, &c->dirty_list) {
551 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
552
553 numblocks ++;
554 dirty += jeb->dirty_size;
555 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
556 printk(JFFS2_DBG "dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
557 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
558 jeb->unchecked_size, jeb->free_size);
559 }
560 }
561
562 printk (JFFS2_DBG "contains %d blocks with total dirty size %u, average dirty size: %u\n",
563 numblocks, dirty, dirty / numblocks);
564 }
565
566 if (list_empty(&c->erasable_list)) {
567 printk(JFFS2_DBG "erasable_list: empty\n");
568 } else {
569 struct list_head *this;
570
571 list_for_each(this, &c->erasable_list) {
572 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
573
574 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
575 printk(JFFS2_DBG "erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
576 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
577 jeb->unchecked_size, jeb->free_size);
578 }
579 }
580 }
581
582 if (list_empty(&c->erasing_list)) {
583 printk(JFFS2_DBG "erasing_list: empty\n");
584 } else {
585 struct list_head *this;
586
587 list_for_each(this, &c->erasing_list) {
588 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
589
590 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
591 printk(JFFS2_DBG "erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
592 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
593 jeb->unchecked_size, jeb->free_size);
594 }
595 }
596 }
597 if (list_empty(&c->erase_checking_list)) {
598 printk(JFFS2_DBG "erase_checking_list: empty\n");
599 } else {
600 struct list_head *this;
601
602 list_for_each(this, &c->erase_checking_list) {
603 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
604
605 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
606 printk(JFFS2_DBG "erase_checking_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
607 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
608 jeb->unchecked_size, jeb->free_size);
609 }
610 }
611 }
612
613 if (list_empty(&c->erase_pending_list)) {
614 printk(JFFS2_DBG "erase_pending_list: empty\n");
615 } else {
616 struct list_head *this;
617
618 list_for_each(this, &c->erase_pending_list) {
619 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
620
621 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
622 printk(JFFS2_DBG "erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
623 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
624 jeb->unchecked_size, jeb->free_size);
625 }
626 }
627 }
628
629 if (list_empty(&c->erasable_pending_wbuf_list)) {
630 printk(JFFS2_DBG "erasable_pending_wbuf_list: empty\n");
631 } else {
632 struct list_head *this;
633
634 list_for_each(this, &c->erasable_pending_wbuf_list) {
635 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
636
637 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
638 printk(JFFS2_DBG "erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
639 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
640 jeb->unchecked_size, jeb->free_size);
641 }
642 }
643 }
644
645 if (list_empty(&c->free_list)) {
646 printk(JFFS2_DBG "free_list: empty\n");
647 } else {
648 struct list_head *this;
649
650 list_for_each(this, &c->free_list) {
651 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
652
653 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
654 printk(JFFS2_DBG "free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
655 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
656 jeb->unchecked_size, jeb->free_size);
657 }
658 }
659 }
660
661 if (list_empty(&c->bad_list)) {
662 printk(JFFS2_DBG "bad_list: empty\n");
663 } else {
664 struct list_head *this;
665
666 list_for_each(this, &c->bad_list) {
667 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
668
669 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
670 printk(JFFS2_DBG "bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
671 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
672 jeb->unchecked_size, jeb->free_size);
673 }
674 }
675 }
676
677 if (list_empty(&c->bad_used_list)) {
678 printk(JFFS2_DBG "bad_used_list: empty\n");
679 } else {
680 struct list_head *this;
681
682 list_for_each(this, &c->bad_used_list) {
683 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
684
685 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
686 printk(JFFS2_DBG "bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
687 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
688 jeb->unchecked_size, jeb->free_size);
689 }
690 }
691 }
692}
693
694void
695__jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f)
696{
697 mutex_lock(&f->sem);
698 jffs2_dbg_dump_fragtree_nolock(f);
699 mutex_unlock(&f->sem);
700}
701
702void
703__jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f)
704{
705 struct jffs2_node_frag *this = frag_first(&f->fragtree);
706 uint32_t lastofs = 0;
707 int buggy = 0;
708
709 printk(JFFS2_DBG_MSG_PREFIX " dump fragtree of ino #%u\n", f->inocache->ino);
710 while(this) {
711 if (this->node)
712 printk(JFFS2_DBG "frag %#04x-%#04x: %#08x(%d) on flash (*%p), left (%p), right (%p), parent (%p)\n",
713 this->ofs, this->ofs+this->size, ref_offset(this->node->raw),
714 ref_flags(this->node->raw), this, frag_left(this), frag_right(this),
715 frag_parent(this));
716 else
717 printk(JFFS2_DBG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n",
718 this->ofs, this->ofs+this->size, this, frag_left(this),
719 frag_right(this), frag_parent(this));
720 if (this->ofs != lastofs)
721 buggy = 1;
722 lastofs = this->ofs + this->size;
723 this = frag_next(this);
724 }
725
726 if (f->metadata)
727 printk(JFFS2_DBG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
728
729 if (buggy) {
730 JFFS2_ERROR("frag tree got a hole in it.\n");
731 BUG();
732 }
733}
734
735#define JFFS2_BUFDUMP_BYTES_PER_LINE 32
736void
737__jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs)
738{
739 int skip;
740 int i;
741
742 printk(JFFS2_DBG_MSG_PREFIX " dump from offset %#08x to offset %#08x (%x bytes).\n",
743 offs, offs + len, len);
744 i = skip = offs % JFFS2_BUFDUMP_BYTES_PER_LINE;
745 offs = offs & ~(JFFS2_BUFDUMP_BYTES_PER_LINE - 1);
746
747 if (skip != 0)
748 printk(JFFS2_DBG "%#08x: ", offs);
749
750 while (skip--)
751 printk(" ");
752
753 while (i < len) {
754 if ((i % JFFS2_BUFDUMP_BYTES_PER_LINE) == 0 && i != len -1) {
755 if (i != 0)
756 printk("\n");
757 offs += JFFS2_BUFDUMP_BYTES_PER_LINE;
758 printk(JFFS2_DBG "%0#8x: ", offs);
759 }
760
761 printk("%02x ", buf[i]);
762
763 i += 1;
764 }
765
766 printk("\n");
767}
768
769/*
770 * Dump a JFFS2 node.
771 */
772void
773__jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs)
774{
775 union jffs2_node_union node;
776 int len = sizeof(union jffs2_node_union);
777 size_t retlen;
778 uint32_t crc;
779 int ret;
780
781 printk(JFFS2_DBG_MSG_PREFIX " dump node at offset %#08x.\n", ofs);
782
783 ret = jffs2_flash_read(c, ofs, len, &retlen, (unsigned char *)&node);
784 if (ret || (retlen != len)) {
785 JFFS2_ERROR("read %d bytes failed or short. ret %d, retlen %zd.\n",
786 len, ret, retlen);
787 return;
788 }
789
790 printk(JFFS2_DBG "magic:\t%#04x\n", je16_to_cpu(node.u.magic));
791 printk(JFFS2_DBG "nodetype:\t%#04x\n", je16_to_cpu(node.u.nodetype));
792 printk(JFFS2_DBG "totlen:\t%#08x\n", je32_to_cpu(node.u.totlen));
793 printk(JFFS2_DBG "hdr_crc:\t%#08x\n", je32_to_cpu(node.u.hdr_crc));
794
795 crc = crc32(0, &node.u, sizeof(node.u) - 4);
796 if (crc != je32_to_cpu(node.u.hdr_crc)) {
797 JFFS2_ERROR("wrong common header CRC.\n");
798 return;
799 }
800
801 if (je16_to_cpu(node.u.magic) != JFFS2_MAGIC_BITMASK &&
802 je16_to_cpu(node.u.magic) != JFFS2_OLD_MAGIC_BITMASK)
803 {
804 JFFS2_ERROR("wrong node magic: %#04x instead of %#04x.\n",
805 je16_to_cpu(node.u.magic), JFFS2_MAGIC_BITMASK);
806 return;
807 }
808
809 switch(je16_to_cpu(node.u.nodetype)) {
810
811 case JFFS2_NODETYPE_INODE:
812
813 printk(JFFS2_DBG "the node is inode node\n");
814 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.i.ino));
815 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.i.version));
816 printk(JFFS2_DBG "mode:\t%#08x\n", node.i.mode.m);
817 printk(JFFS2_DBG "uid:\t%#04x\n", je16_to_cpu(node.i.uid));
818 printk(JFFS2_DBG "gid:\t%#04x\n", je16_to_cpu(node.i.gid));
819 printk(JFFS2_DBG "isize:\t%#08x\n", je32_to_cpu(node.i.isize));
820 printk(JFFS2_DBG "atime:\t%#08x\n", je32_to_cpu(node.i.atime));
821 printk(JFFS2_DBG "mtime:\t%#08x\n", je32_to_cpu(node.i.mtime));
822 printk(JFFS2_DBG "ctime:\t%#08x\n", je32_to_cpu(node.i.ctime));
823 printk(JFFS2_DBG "offset:\t%#08x\n", je32_to_cpu(node.i.offset));
824 printk(JFFS2_DBG "csize:\t%#08x\n", je32_to_cpu(node.i.csize));
825 printk(JFFS2_DBG "dsize:\t%#08x\n", je32_to_cpu(node.i.dsize));
826 printk(JFFS2_DBG "compr:\t%#02x\n", node.i.compr);
827 printk(JFFS2_DBG "usercompr:\t%#02x\n", node.i.usercompr);
828 printk(JFFS2_DBG "flags:\t%#04x\n", je16_to_cpu(node.i.flags));
829 printk(JFFS2_DBG "data_crc:\t%#08x\n", je32_to_cpu(node.i.data_crc));
830 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.i.node_crc));
831
832 crc = crc32(0, &node.i, sizeof(node.i) - 8);
833 if (crc != je32_to_cpu(node.i.node_crc)) {
834 JFFS2_ERROR("wrong node header CRC.\n");
835 return;
836 }
837 break;
838
839 case JFFS2_NODETYPE_DIRENT:
840
841 printk(JFFS2_DBG "the node is dirent node\n");
842 printk(JFFS2_DBG "pino:\t%#08x\n", je32_to_cpu(node.d.pino));
843 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.d.version));
844 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.d.ino));
845 printk(JFFS2_DBG "mctime:\t%#08x\n", je32_to_cpu(node.d.mctime));
846 printk(JFFS2_DBG "nsize:\t%#02x\n", node.d.nsize);
847 printk(JFFS2_DBG "type:\t%#02x\n", node.d.type);
848 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.d.node_crc));
849 printk(JFFS2_DBG "name_crc:\t%#08x\n", je32_to_cpu(node.d.name_crc));
850
851 node.d.name[node.d.nsize] = '\0';
852 printk(JFFS2_DBG "name:\t\"%s\"\n", node.d.name);
853
854 crc = crc32(0, &node.d, sizeof(node.d) - 8);
855 if (crc != je32_to_cpu(node.d.node_crc)) {
856 JFFS2_ERROR("wrong node header CRC.\n");
857 return;
858 }
859 break;
860
861 default:
862 printk(JFFS2_DBG "node type is unknown\n");
863 break;
864 }
865}
866#endif /* JFFS2_DBG_DUMPS || JFFS2_DBG_PARANOIA_CHECKS */
1/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
4 * Copyright © 2001-2007 Red Hat, Inc.
5 * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
6 *
7 * Created by David Woodhouse <dwmw2@infradead.org>
8 *
9 * For licensing information, see the file 'LICENCE' in this directory.
10 *
11 */
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/pagemap.h>
16#include <linux/crc32.h>
17#include <linux/jffs2.h>
18#include <linux/mtd/mtd.h>
19#include <linux/slab.h>
20#include "nodelist.h"
21#include "debug.h"
22
23#ifdef JFFS2_DBG_SANITY_CHECKS
24
25void
26__jffs2_dbg_acct_sanity_check_nolock(struct jffs2_sb_info *c,
27 struct jffs2_eraseblock *jeb)
28{
29 if (unlikely(jeb && jeb->used_size + jeb->dirty_size +
30 jeb->free_size + jeb->wasted_size +
31 jeb->unchecked_size != c->sector_size)) {
32 JFFS2_ERROR("eeep, space accounting for block at 0x%08x is screwed.\n", jeb->offset);
33 JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
34 jeb->free_size, jeb->dirty_size, jeb->used_size,
35 jeb->wasted_size, jeb->unchecked_size, c->sector_size);
36 BUG();
37 }
38
39 if (unlikely(c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size
40 + c->wasted_size + c->unchecked_size != c->flash_size)) {
41 JFFS2_ERROR("eeep, space accounting superblock info is screwed.\n");
42 JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + erasing %#08x + bad %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
43 c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size,
44 c->wasted_size, c->unchecked_size, c->flash_size);
45 BUG();
46 }
47}
48
49void
50__jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c,
51 struct jffs2_eraseblock *jeb)
52{
53 spin_lock(&c->erase_completion_lock);
54 jffs2_dbg_acct_sanity_check_nolock(c, jeb);
55 spin_unlock(&c->erase_completion_lock);
56}
57
58#endif /* JFFS2_DBG_SANITY_CHECKS */
59
60#ifdef JFFS2_DBG_PARANOIA_CHECKS
61/*
62 * Check the fragtree.
63 */
64void
65__jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f)
66{
67 mutex_lock(&f->sem);
68 __jffs2_dbg_fragtree_paranoia_check_nolock(f);
69 mutex_unlock(&f->sem);
70}
71
72void
73__jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f)
74{
75 struct jffs2_node_frag *frag;
76 int bitched = 0;
77
78 for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
79 struct jffs2_full_dnode *fn = frag->node;
80
81 if (!fn || !fn->raw)
82 continue;
83
84 if (ref_flags(fn->raw) == REF_PRISTINE) {
85 if (fn->frags > 1) {
86 JFFS2_ERROR("REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2.\n",
87 ref_offset(fn->raw), fn->frags);
88 bitched = 1;
89 }
90
91 /* A hole node which isn't multi-page should be garbage-collected
92 and merged anyway, so we just check for the frag size here,
93 rather than mucking around with actually reading the node
94 and checking the compression type, which is the real way
95 to tell a hole node. */
96 if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag)
97 && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) {
98 JFFS2_ERROR("REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2.\n",
99 ref_offset(fn->raw));
100 bitched = 1;
101 }
102
103 if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag)
104 && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) {
105 JFFS2_ERROR("REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2.\n",
106 ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size);
107 bitched = 1;
108 }
109 }
110 }
111
112 if (bitched) {
113 JFFS2_ERROR("fragtree is corrupted.\n");
114 __jffs2_dbg_dump_fragtree_nolock(f);
115 BUG();
116 }
117}
118
119/*
120 * Check if the flash contains all 0xFF before we start writing.
121 */
122void
123__jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
124 uint32_t ofs, int len)
125{
126 size_t retlen;
127 int ret, i;
128 unsigned char *buf;
129
130 buf = kmalloc(len, GFP_KERNEL);
131 if (!buf)
132 return;
133
134 ret = jffs2_flash_read(c, ofs, len, &retlen, buf);
135 if (ret || (retlen != len)) {
136 JFFS2_WARNING("read %d bytes failed or short. ret %d, retlen %zd.\n",
137 len, ret, retlen);
138 kfree(buf);
139 return;
140 }
141
142 ret = 0;
143 for (i = 0; i < len; i++)
144 if (buf[i] != 0xff)
145 ret = 1;
146
147 if (ret) {
148 JFFS2_ERROR("argh, about to write node to %#08x on flash, but there are data already there. The first corrupted byte is at %#08x offset.\n",
149 ofs, ofs + i);
150 __jffs2_dbg_dump_buffer(buf, len, ofs);
151 kfree(buf);
152 BUG();
153 }
154
155 kfree(buf);
156}
157
158void __jffs2_dbg_superblock_counts(struct jffs2_sb_info *c)
159{
160 struct jffs2_eraseblock *jeb;
161 uint32_t free = 0, dirty = 0, used = 0, wasted = 0,
162 erasing = 0, bad = 0, unchecked = 0;
163 int nr_counted = 0;
164 int dump = 0;
165
166 if (c->gcblock) {
167 nr_counted++;
168 free += c->gcblock->free_size;
169 dirty += c->gcblock->dirty_size;
170 used += c->gcblock->used_size;
171 wasted += c->gcblock->wasted_size;
172 unchecked += c->gcblock->unchecked_size;
173 }
174 if (c->nextblock) {
175 nr_counted++;
176 free += c->nextblock->free_size;
177 dirty += c->nextblock->dirty_size;
178 used += c->nextblock->used_size;
179 wasted += c->nextblock->wasted_size;
180 unchecked += c->nextblock->unchecked_size;
181 }
182 list_for_each_entry(jeb, &c->clean_list, list) {
183 nr_counted++;
184 free += jeb->free_size;
185 dirty += jeb->dirty_size;
186 used += jeb->used_size;
187 wasted += jeb->wasted_size;
188 unchecked += jeb->unchecked_size;
189 }
190 list_for_each_entry(jeb, &c->very_dirty_list, list) {
191 nr_counted++;
192 free += jeb->free_size;
193 dirty += jeb->dirty_size;
194 used += jeb->used_size;
195 wasted += jeb->wasted_size;
196 unchecked += jeb->unchecked_size;
197 }
198 list_for_each_entry(jeb, &c->dirty_list, list) {
199 nr_counted++;
200 free += jeb->free_size;
201 dirty += jeb->dirty_size;
202 used += jeb->used_size;
203 wasted += jeb->wasted_size;
204 unchecked += jeb->unchecked_size;
205 }
206 list_for_each_entry(jeb, &c->erasable_list, list) {
207 nr_counted++;
208 free += jeb->free_size;
209 dirty += jeb->dirty_size;
210 used += jeb->used_size;
211 wasted += jeb->wasted_size;
212 unchecked += jeb->unchecked_size;
213 }
214 list_for_each_entry(jeb, &c->erasable_pending_wbuf_list, list) {
215 nr_counted++;
216 free += jeb->free_size;
217 dirty += jeb->dirty_size;
218 used += jeb->used_size;
219 wasted += jeb->wasted_size;
220 unchecked += jeb->unchecked_size;
221 }
222 list_for_each_entry(jeb, &c->erase_pending_list, list) {
223 nr_counted++;
224 free += jeb->free_size;
225 dirty += jeb->dirty_size;
226 used += jeb->used_size;
227 wasted += jeb->wasted_size;
228 unchecked += jeb->unchecked_size;
229 }
230 list_for_each_entry(jeb, &c->free_list, list) {
231 nr_counted++;
232 free += jeb->free_size;
233 dirty += jeb->dirty_size;
234 used += jeb->used_size;
235 wasted += jeb->wasted_size;
236 unchecked += jeb->unchecked_size;
237 }
238 list_for_each_entry(jeb, &c->bad_used_list, list) {
239 nr_counted++;
240 free += jeb->free_size;
241 dirty += jeb->dirty_size;
242 used += jeb->used_size;
243 wasted += jeb->wasted_size;
244 unchecked += jeb->unchecked_size;
245 }
246
247 list_for_each_entry(jeb, &c->erasing_list, list) {
248 nr_counted++;
249 erasing += c->sector_size;
250 }
251 list_for_each_entry(jeb, &c->erase_checking_list, list) {
252 nr_counted++;
253 erasing += c->sector_size;
254 }
255 list_for_each_entry(jeb, &c->erase_complete_list, list) {
256 nr_counted++;
257 erasing += c->sector_size;
258 }
259 list_for_each_entry(jeb, &c->bad_list, list) {
260 nr_counted++;
261 bad += c->sector_size;
262 }
263
264#define check(sz) \
265 if (sz != c->sz##_size) { \
266 printk(KERN_WARNING #sz "_size mismatch counted 0x%x, c->" #sz "_size 0x%x\n", \
267 sz, c->sz##_size); \
268 dump = 1; \
269 }
270 check(free);
271 check(dirty);
272 check(used);
273 check(wasted);
274 check(unchecked);
275 check(bad);
276 check(erasing);
277#undef check
278
279 if (nr_counted != c->nr_blocks) {
280 printk(KERN_WARNING "%s counted only 0x%x blocks of 0x%x. Where are the others?\n",
281 __func__, nr_counted, c->nr_blocks);
282 dump = 1;
283 }
284
285 if (dump) {
286 __jffs2_dbg_dump_block_lists_nolock(c);
287 BUG();
288 }
289}
290
291/*
292 * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
293 */
294void
295__jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c,
296 struct jffs2_eraseblock *jeb)
297{
298 spin_lock(&c->erase_completion_lock);
299 __jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
300 spin_unlock(&c->erase_completion_lock);
301}
302
303void
304__jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
305 struct jffs2_eraseblock *jeb)
306{
307 uint32_t my_used_size = 0;
308 uint32_t my_unchecked_size = 0;
309 uint32_t my_dirty_size = 0;
310 struct jffs2_raw_node_ref *ref2 = jeb->first_node;
311
312 while (ref2) {
313 uint32_t totlen = ref_totlen(c, jeb, ref2);
314
315 if (ref_offset(ref2) < jeb->offset ||
316 ref_offset(ref2) > jeb->offset + c->sector_size) {
317 JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.\n",
318 ref_offset(ref2), jeb->offset);
319 goto error;
320
321 }
322 if (ref_flags(ref2) == REF_UNCHECKED)
323 my_unchecked_size += totlen;
324 else if (!ref_obsolete(ref2))
325 my_used_size += totlen;
326 else
327 my_dirty_size += totlen;
328
329 if ((!ref_next(ref2)) != (ref2 == jeb->last_node)) {
330 JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next at %#08x (mem %p), last_node is at %#08x (mem %p).\n",
331 ref_offset(ref2), ref2, ref_offset(ref_next(ref2)), ref_next(ref2),
332 ref_offset(jeb->last_node), jeb->last_node);
333 goto error;
334 }
335 ref2 = ref_next(ref2);
336 }
337
338 if (my_used_size != jeb->used_size) {
339 JFFS2_ERROR("Calculated used size %#08x != stored used size %#08x.\n",
340 my_used_size, jeb->used_size);
341 goto error;
342 }
343
344 if (my_unchecked_size != jeb->unchecked_size) {
345 JFFS2_ERROR("Calculated unchecked size %#08x != stored unchecked size %#08x.\n",
346 my_unchecked_size, jeb->unchecked_size);
347 goto error;
348 }
349
350#if 0
351 /* This should work when we implement ref->__totlen elemination */
352 if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) {
353 JFFS2_ERROR("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n",
354 my_dirty_size, jeb->dirty_size + jeb->wasted_size);
355 goto error;
356 }
357
358 if (jeb->free_size == 0
359 && my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) {
360 JFFS2_ERROR("The sum of all nodes in block (%#x) != size of block (%#x)\n",
361 my_used_size + my_unchecked_size + my_dirty_size,
362 c->sector_size);
363 goto error;
364 }
365#endif
366
367 if (!(c->flags & (JFFS2_SB_FLAG_BUILDING|JFFS2_SB_FLAG_SCANNING)))
368 __jffs2_dbg_superblock_counts(c);
369
370 return;
371
372error:
373 __jffs2_dbg_dump_node_refs_nolock(c, jeb);
374 __jffs2_dbg_dump_jeb_nolock(jeb);
375 __jffs2_dbg_dump_block_lists_nolock(c);
376 BUG();
377
378}
379#endif /* JFFS2_DBG_PARANOIA_CHECKS */
380
381#if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS)
382/*
383 * Dump the node_refs of the 'jeb' JFFS2 eraseblock.
384 */
385void
386__jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c,
387 struct jffs2_eraseblock *jeb)
388{
389 spin_lock(&c->erase_completion_lock);
390 __jffs2_dbg_dump_node_refs_nolock(c, jeb);
391 spin_unlock(&c->erase_completion_lock);
392}
393
394void
395__jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c,
396 struct jffs2_eraseblock *jeb)
397{
398 struct jffs2_raw_node_ref *ref;
399 int i = 0;
400
401 printk(JFFS2_DBG_MSG_PREFIX " Dump node_refs of the eraseblock %#08x\n", jeb->offset);
402 if (!jeb->first_node) {
403 printk(JFFS2_DBG_MSG_PREFIX " no nodes in the eraseblock %#08x\n", jeb->offset);
404 return;
405 }
406
407 printk(JFFS2_DBG);
408 for (ref = jeb->first_node; ; ref = ref_next(ref)) {
409 printk("%#08x", ref_offset(ref));
410#ifdef TEST_TOTLEN
411 printk("(%x)", ref->__totlen);
412#endif
413 if (ref_next(ref))
414 printk("->");
415 else
416 break;
417 if (++i == 4) {
418 i = 0;
419 printk("\n" JFFS2_DBG);
420 }
421 }
422 printk("\n");
423}
424
425/*
426 * Dump an eraseblock's space accounting.
427 */
428void
429__jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
430{
431 spin_lock(&c->erase_completion_lock);
432 __jffs2_dbg_dump_jeb_nolock(jeb);
433 spin_unlock(&c->erase_completion_lock);
434}
435
436void
437__jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb)
438{
439 if (!jeb)
440 return;
441
442 printk(JFFS2_DBG_MSG_PREFIX " dump space accounting for the eraseblock at %#08x:\n",
443 jeb->offset);
444
445 printk(JFFS2_DBG "used_size: %#08x\n", jeb->used_size);
446 printk(JFFS2_DBG "dirty_size: %#08x\n", jeb->dirty_size);
447 printk(JFFS2_DBG "wasted_size: %#08x\n", jeb->wasted_size);
448 printk(JFFS2_DBG "unchecked_size: %#08x\n", jeb->unchecked_size);
449 printk(JFFS2_DBG "free_size: %#08x\n", jeb->free_size);
450}
451
452void
453__jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c)
454{
455 spin_lock(&c->erase_completion_lock);
456 __jffs2_dbg_dump_block_lists_nolock(c);
457 spin_unlock(&c->erase_completion_lock);
458}
459
460void
461__jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c)
462{
463 printk(JFFS2_DBG_MSG_PREFIX " dump JFFS2 blocks lists:\n");
464
465 printk(JFFS2_DBG "flash_size: %#08x\n", c->flash_size);
466 printk(JFFS2_DBG "used_size: %#08x\n", c->used_size);
467 printk(JFFS2_DBG "dirty_size: %#08x\n", c->dirty_size);
468 printk(JFFS2_DBG "wasted_size: %#08x\n", c->wasted_size);
469 printk(JFFS2_DBG "unchecked_size: %#08x\n", c->unchecked_size);
470 printk(JFFS2_DBG "free_size: %#08x\n", c->free_size);
471 printk(JFFS2_DBG "erasing_size: %#08x\n", c->erasing_size);
472 printk(JFFS2_DBG "bad_size: %#08x\n", c->bad_size);
473 printk(JFFS2_DBG "sector_size: %#08x\n", c->sector_size);
474 printk(JFFS2_DBG "jffs2_reserved_blocks size: %#08x\n",
475 c->sector_size * c->resv_blocks_write);
476
477 if (c->nextblock)
478 printk(JFFS2_DBG "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
479 c->nextblock->offset, c->nextblock->used_size,
480 c->nextblock->dirty_size, c->nextblock->wasted_size,
481 c->nextblock->unchecked_size, c->nextblock->free_size);
482 else
483 printk(JFFS2_DBG "nextblock: NULL\n");
484
485 if (c->gcblock)
486 printk(JFFS2_DBG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
487 c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size,
488 c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
489 else
490 printk(JFFS2_DBG "gcblock: NULL\n");
491
492 if (list_empty(&c->clean_list)) {
493 printk(JFFS2_DBG "clean_list: empty\n");
494 } else {
495 struct list_head *this;
496 int numblocks = 0;
497 uint32_t dirty = 0;
498
499 list_for_each(this, &c->clean_list) {
500 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
501 numblocks ++;
502 dirty += jeb->wasted_size;
503 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
504 printk(JFFS2_DBG "clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
505 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
506 jeb->unchecked_size, jeb->free_size);
507 }
508 }
509
510 printk (JFFS2_DBG "Contains %d blocks with total wasted size %u, average wasted size: %u\n",
511 numblocks, dirty, dirty / numblocks);
512 }
513
514 if (list_empty(&c->very_dirty_list)) {
515 printk(JFFS2_DBG "very_dirty_list: empty\n");
516 } else {
517 struct list_head *this;
518 int numblocks = 0;
519 uint32_t dirty = 0;
520
521 list_for_each(this, &c->very_dirty_list) {
522 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
523
524 numblocks ++;
525 dirty += jeb->dirty_size;
526 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
527 printk(JFFS2_DBG "very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
528 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
529 jeb->unchecked_size, jeb->free_size);
530 }
531 }
532
533 printk (JFFS2_DBG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
534 numblocks, dirty, dirty / numblocks);
535 }
536
537 if (list_empty(&c->dirty_list)) {
538 printk(JFFS2_DBG "dirty_list: empty\n");
539 } else {
540 struct list_head *this;
541 int numblocks = 0;
542 uint32_t dirty = 0;
543
544 list_for_each(this, &c->dirty_list) {
545 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
546
547 numblocks ++;
548 dirty += jeb->dirty_size;
549 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
550 printk(JFFS2_DBG "dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
551 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
552 jeb->unchecked_size, jeb->free_size);
553 }
554 }
555
556 printk (JFFS2_DBG "contains %d blocks with total dirty size %u, average dirty size: %u\n",
557 numblocks, dirty, dirty / numblocks);
558 }
559
560 if (list_empty(&c->erasable_list)) {
561 printk(JFFS2_DBG "erasable_list: empty\n");
562 } else {
563 struct list_head *this;
564
565 list_for_each(this, &c->erasable_list) {
566 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
567
568 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
569 printk(JFFS2_DBG "erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
570 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
571 jeb->unchecked_size, jeb->free_size);
572 }
573 }
574 }
575
576 if (list_empty(&c->erasing_list)) {
577 printk(JFFS2_DBG "erasing_list: empty\n");
578 } else {
579 struct list_head *this;
580
581 list_for_each(this, &c->erasing_list) {
582 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
583
584 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
585 printk(JFFS2_DBG "erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
586 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
587 jeb->unchecked_size, jeb->free_size);
588 }
589 }
590 }
591 if (list_empty(&c->erase_checking_list)) {
592 printk(JFFS2_DBG "erase_checking_list: empty\n");
593 } else {
594 struct list_head *this;
595
596 list_for_each(this, &c->erase_checking_list) {
597 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
598
599 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
600 printk(JFFS2_DBG "erase_checking_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
601 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
602 jeb->unchecked_size, jeb->free_size);
603 }
604 }
605 }
606
607 if (list_empty(&c->erase_pending_list)) {
608 printk(JFFS2_DBG "erase_pending_list: empty\n");
609 } else {
610 struct list_head *this;
611
612 list_for_each(this, &c->erase_pending_list) {
613 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
614
615 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
616 printk(JFFS2_DBG "erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
617 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
618 jeb->unchecked_size, jeb->free_size);
619 }
620 }
621 }
622
623 if (list_empty(&c->erasable_pending_wbuf_list)) {
624 printk(JFFS2_DBG "erasable_pending_wbuf_list: empty\n");
625 } else {
626 struct list_head *this;
627
628 list_for_each(this, &c->erasable_pending_wbuf_list) {
629 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
630
631 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
632 printk(JFFS2_DBG "erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
633 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
634 jeb->unchecked_size, jeb->free_size);
635 }
636 }
637 }
638
639 if (list_empty(&c->free_list)) {
640 printk(JFFS2_DBG "free_list: empty\n");
641 } else {
642 struct list_head *this;
643
644 list_for_each(this, &c->free_list) {
645 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
646
647 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
648 printk(JFFS2_DBG "free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
649 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
650 jeb->unchecked_size, jeb->free_size);
651 }
652 }
653 }
654
655 if (list_empty(&c->bad_list)) {
656 printk(JFFS2_DBG "bad_list: empty\n");
657 } else {
658 struct list_head *this;
659
660 list_for_each(this, &c->bad_list) {
661 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
662
663 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
664 printk(JFFS2_DBG "bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
665 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
666 jeb->unchecked_size, jeb->free_size);
667 }
668 }
669 }
670
671 if (list_empty(&c->bad_used_list)) {
672 printk(JFFS2_DBG "bad_used_list: empty\n");
673 } else {
674 struct list_head *this;
675
676 list_for_each(this, &c->bad_used_list) {
677 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
678
679 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
680 printk(JFFS2_DBG "bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
681 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
682 jeb->unchecked_size, jeb->free_size);
683 }
684 }
685 }
686}
687
688void
689__jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f)
690{
691 mutex_lock(&f->sem);
692 jffs2_dbg_dump_fragtree_nolock(f);
693 mutex_unlock(&f->sem);
694}
695
696void
697__jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f)
698{
699 struct jffs2_node_frag *this = frag_first(&f->fragtree);
700 uint32_t lastofs = 0;
701 int buggy = 0;
702
703 printk(JFFS2_DBG_MSG_PREFIX " dump fragtree of ino #%u\n", f->inocache->ino);
704 while(this) {
705 if (this->node)
706 printk(JFFS2_DBG "frag %#04x-%#04x: %#08x(%d) on flash (*%p), left (%p), right (%p), parent (%p)\n",
707 this->ofs, this->ofs+this->size, ref_offset(this->node->raw),
708 ref_flags(this->node->raw), this, frag_left(this), frag_right(this),
709 frag_parent(this));
710 else
711 printk(JFFS2_DBG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n",
712 this->ofs, this->ofs+this->size, this, frag_left(this),
713 frag_right(this), frag_parent(this));
714 if (this->ofs != lastofs)
715 buggy = 1;
716 lastofs = this->ofs + this->size;
717 this = frag_next(this);
718 }
719
720 if (f->metadata)
721 printk(JFFS2_DBG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
722
723 if (buggy) {
724 JFFS2_ERROR("frag tree got a hole in it.\n");
725 BUG();
726 }
727}
728
729#define JFFS2_BUFDUMP_BYTES_PER_LINE 32
730void
731__jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs)
732{
733 int skip;
734 int i;
735
736 printk(JFFS2_DBG_MSG_PREFIX " dump from offset %#08x to offset %#08x (%x bytes).\n",
737 offs, offs + len, len);
738 i = skip = offs % JFFS2_BUFDUMP_BYTES_PER_LINE;
739 offs = offs & ~(JFFS2_BUFDUMP_BYTES_PER_LINE - 1);
740
741 if (skip != 0)
742 printk(JFFS2_DBG "%#08x: ", offs);
743
744 while (skip--)
745 printk(" ");
746
747 while (i < len) {
748 if ((i % JFFS2_BUFDUMP_BYTES_PER_LINE) == 0 && i != len -1) {
749 if (i != 0)
750 printk("\n");
751 offs += JFFS2_BUFDUMP_BYTES_PER_LINE;
752 printk(JFFS2_DBG "%0#8x: ", offs);
753 }
754
755 printk("%02x ", buf[i]);
756
757 i += 1;
758 }
759
760 printk("\n");
761}
762
763/*
764 * Dump a JFFS2 node.
765 */
766void
767__jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs)
768{
769 union jffs2_node_union node;
770 int len = sizeof(union jffs2_node_union);
771 size_t retlen;
772 uint32_t crc;
773 int ret;
774
775 printk(JFFS2_DBG_MSG_PREFIX " dump node at offset %#08x.\n", ofs);
776
777 ret = jffs2_flash_read(c, ofs, len, &retlen, (unsigned char *)&node);
778 if (ret || (retlen != len)) {
779 JFFS2_ERROR("read %d bytes failed or short. ret %d, retlen %zd.\n",
780 len, ret, retlen);
781 return;
782 }
783
784 printk(JFFS2_DBG "magic:\t%#04x\n", je16_to_cpu(node.u.magic));
785 printk(JFFS2_DBG "nodetype:\t%#04x\n", je16_to_cpu(node.u.nodetype));
786 printk(JFFS2_DBG "totlen:\t%#08x\n", je32_to_cpu(node.u.totlen));
787 printk(JFFS2_DBG "hdr_crc:\t%#08x\n", je32_to_cpu(node.u.hdr_crc));
788
789 crc = crc32(0, &node.u, sizeof(node.u) - 4);
790 if (crc != je32_to_cpu(node.u.hdr_crc)) {
791 JFFS2_ERROR("wrong common header CRC.\n");
792 return;
793 }
794
795 if (je16_to_cpu(node.u.magic) != JFFS2_MAGIC_BITMASK &&
796 je16_to_cpu(node.u.magic) != JFFS2_OLD_MAGIC_BITMASK)
797 {
798 JFFS2_ERROR("wrong node magic: %#04x instead of %#04x.\n",
799 je16_to_cpu(node.u.magic), JFFS2_MAGIC_BITMASK);
800 return;
801 }
802
803 switch(je16_to_cpu(node.u.nodetype)) {
804
805 case JFFS2_NODETYPE_INODE:
806
807 printk(JFFS2_DBG "the node is inode node\n");
808 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.i.ino));
809 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.i.version));
810 printk(JFFS2_DBG "mode:\t%#08x\n", node.i.mode.m);
811 printk(JFFS2_DBG "uid:\t%#04x\n", je16_to_cpu(node.i.uid));
812 printk(JFFS2_DBG "gid:\t%#04x\n", je16_to_cpu(node.i.gid));
813 printk(JFFS2_DBG "isize:\t%#08x\n", je32_to_cpu(node.i.isize));
814 printk(JFFS2_DBG "atime:\t%#08x\n", je32_to_cpu(node.i.atime));
815 printk(JFFS2_DBG "mtime:\t%#08x\n", je32_to_cpu(node.i.mtime));
816 printk(JFFS2_DBG "ctime:\t%#08x\n", je32_to_cpu(node.i.ctime));
817 printk(JFFS2_DBG "offset:\t%#08x\n", je32_to_cpu(node.i.offset));
818 printk(JFFS2_DBG "csize:\t%#08x\n", je32_to_cpu(node.i.csize));
819 printk(JFFS2_DBG "dsize:\t%#08x\n", je32_to_cpu(node.i.dsize));
820 printk(JFFS2_DBG "compr:\t%#02x\n", node.i.compr);
821 printk(JFFS2_DBG "usercompr:\t%#02x\n", node.i.usercompr);
822 printk(JFFS2_DBG "flags:\t%#04x\n", je16_to_cpu(node.i.flags));
823 printk(JFFS2_DBG "data_crc:\t%#08x\n", je32_to_cpu(node.i.data_crc));
824 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.i.node_crc));
825
826 crc = crc32(0, &node.i, sizeof(node.i) - 8);
827 if (crc != je32_to_cpu(node.i.node_crc)) {
828 JFFS2_ERROR("wrong node header CRC.\n");
829 return;
830 }
831 break;
832
833 case JFFS2_NODETYPE_DIRENT:
834
835 printk(JFFS2_DBG "the node is dirent node\n");
836 printk(JFFS2_DBG "pino:\t%#08x\n", je32_to_cpu(node.d.pino));
837 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.d.version));
838 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.d.ino));
839 printk(JFFS2_DBG "mctime:\t%#08x\n", je32_to_cpu(node.d.mctime));
840 printk(JFFS2_DBG "nsize:\t%#02x\n", node.d.nsize);
841 printk(JFFS2_DBG "type:\t%#02x\n", node.d.type);
842 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.d.node_crc));
843 printk(JFFS2_DBG "name_crc:\t%#08x\n", je32_to_cpu(node.d.name_crc));
844
845 node.d.name[node.d.nsize] = '\0';
846 printk(JFFS2_DBG "name:\t\"%s\"\n", node.d.name);
847
848 crc = crc32(0, &node.d, sizeof(node.d) - 8);
849 if (crc != je32_to_cpu(node.d.node_crc)) {
850 JFFS2_ERROR("wrong node header CRC.\n");
851 return;
852 }
853 break;
854
855 default:
856 printk(JFFS2_DBG "node type is unknown\n");
857 break;
858 }
859}
860#endif /* JFFS2_DBG_DUMPS || JFFS2_DBG_PARANOIA_CHECKS */