GNU Linux-libre 4.9.297-gnu1
[releases.git] / fs / jffs2 / debug.c
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
27 void
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
51 void
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  */
66 void
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
74 void
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  */
124 void
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
160 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)                                                       \
267 do {                                                                    \
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  */
300 void
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
309 void
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
378 error:
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  */
391 void
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
400 void
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  */
434 void
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
442 void
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
458 void
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
466 void
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
694 void
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
702 void
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
736 void
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  */
772 void
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 */