mtd: do not use mtd->block_markbad directly
[linux-2.6.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 #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
25 void
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
49 void
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  */
64 void
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
72 void
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  */
122 void
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
158 void __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  */
294 void
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
303 void
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
372 error:
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  */
385 void
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
394 void
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  */
428 void
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
436 void
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
452 void
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
460 void
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
688 void
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
696 void
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
730 void
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  */
766 void
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 */