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