xref: /openbmc/linux/fs/jffs2/debug.c (revision e2bc322b)
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 */
859