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