xref: /openbmc/linux/fs/jffs2/debug.c (revision da320f05)
1730554d9SArtem B. Bityutskiy /*
2730554d9SArtem B. Bityutskiy  * JFFS2 -- Journalling Flash File System, Version 2.
3730554d9SArtem B. Bityutskiy  *
4c00c310eSDavid Woodhouse  * Copyright © 2001-2007 Red Hat, Inc.
56088c058SDavid Woodhouse  * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
6730554d9SArtem B. Bityutskiy  *
7730554d9SArtem B. Bityutskiy  * Created by David Woodhouse <dwmw2@infradead.org>
8730554d9SArtem B. Bityutskiy  *
9730554d9SArtem B. Bityutskiy  * For licensing information, see the file 'LICENCE' in this directory.
10730554d9SArtem B. Bityutskiy  *
11730554d9SArtem B. Bityutskiy  */
12c00c310eSDavid Woodhouse 
13730554d9SArtem B. Bityutskiy #include <linux/kernel.h>
14737b7661SAndrew Lunn #include <linux/types.h>
15730554d9SArtem B. Bityutskiy #include <linux/pagemap.h>
16e0c8e42fSArtem B. Bityutskiy #include <linux/crc32.h>
17e0c8e42fSArtem B. Bityutskiy #include <linux/jffs2.h>
18733802d9SArtem B. Bityutskiy #include <linux/mtd/mtd.h>
195a0e3ad6STejun Heo #include <linux/slab.h>
20730554d9SArtem B. Bityutskiy #include "nodelist.h"
21730554d9SArtem B. Bityutskiy #include "debug.h"
22730554d9SArtem B. Bityutskiy 
2345ca1b50SArtem B. Bityutskiy #ifdef JFFS2_DBG_SANITY_CHECKS
2445ca1b50SArtem B. Bityutskiy 
2545ca1b50SArtem B. Bityutskiy void
2645ca1b50SArtem B. Bityutskiy __jffs2_dbg_acct_sanity_check_nolock(struct jffs2_sb_info *c,
2745ca1b50SArtem B. Bityutskiy 				     struct jffs2_eraseblock *jeb)
2845ca1b50SArtem B. Bityutskiy {
2945ca1b50SArtem B. Bityutskiy 	if (unlikely(jeb && jeb->used_size + jeb->dirty_size +
3045ca1b50SArtem B. Bityutskiy 			jeb->free_size + jeb->wasted_size +
3145ca1b50SArtem B. Bityutskiy 			jeb->unchecked_size != c->sector_size)) {
3245ca1b50SArtem B. Bityutskiy 		JFFS2_ERROR("eeep, space accounting for block at 0x%08x is screwed.\n", jeb->offset);
3381e39cf0SArtem B. Bityutskiy 		JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
3481e39cf0SArtem B. Bityutskiy 			jeb->free_size, jeb->dirty_size, jeb->used_size,
3545ca1b50SArtem B. Bityutskiy 			jeb->wasted_size, jeb->unchecked_size, c->sector_size);
3645ca1b50SArtem B. Bityutskiy 		BUG();
3745ca1b50SArtem B. Bityutskiy 	}
3845ca1b50SArtem B. Bityutskiy 
3945ca1b50SArtem B. Bityutskiy 	if (unlikely(c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size
4045ca1b50SArtem B. Bityutskiy 				+ c->wasted_size + c->unchecked_size != c->flash_size)) {
4145ca1b50SArtem B. Bityutskiy 		JFFS2_ERROR("eeep, space accounting superblock info is screwed.\n");
4281e39cf0SArtem B. Bityutskiy 		JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + erasing %#08x + bad %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
4345ca1b50SArtem B. Bityutskiy 			c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size,
4445ca1b50SArtem B. Bityutskiy 			c->wasted_size, c->unchecked_size, c->flash_size);
4545ca1b50SArtem B. Bityutskiy 		BUG();
4645ca1b50SArtem B. Bityutskiy 	}
4745ca1b50SArtem B. Bityutskiy }
4845ca1b50SArtem B. Bityutskiy 
4945ca1b50SArtem B. Bityutskiy void
5045ca1b50SArtem B. Bityutskiy __jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c,
5145ca1b50SArtem B. Bityutskiy 			      struct jffs2_eraseblock *jeb)
5245ca1b50SArtem B. Bityutskiy {
5345ca1b50SArtem B. Bityutskiy 	spin_lock(&c->erase_completion_lock);
5445ca1b50SArtem B. Bityutskiy 	jffs2_dbg_acct_sanity_check_nolock(c, jeb);
5545ca1b50SArtem B. Bityutskiy 	spin_unlock(&c->erase_completion_lock);
5645ca1b50SArtem B. Bityutskiy }
5745ca1b50SArtem B. Bityutskiy 
5845ca1b50SArtem B. Bityutskiy #endif /* JFFS2_DBG_SANITY_CHECKS */
5945ca1b50SArtem B. Bityutskiy 
60730554d9SArtem B. Bityutskiy #ifdef JFFS2_DBG_PARANOIA_CHECKS
61e0c8e42fSArtem B. Bityutskiy /*
62e0c8e42fSArtem B. Bityutskiy  * Check the fragtree.
63e0c8e42fSArtem B. Bityutskiy  */
64e0c8e42fSArtem B. Bityutskiy void
65e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f)
66e0c8e42fSArtem B. Bityutskiy {
67ced22070SDavid Woodhouse 	mutex_lock(&f->sem);
68e0c8e42fSArtem B. Bityutskiy 	__jffs2_dbg_fragtree_paranoia_check_nolock(f);
69ced22070SDavid Woodhouse 	mutex_unlock(&f->sem);
70e0c8e42fSArtem B. Bityutskiy }
71730554d9SArtem B. Bityutskiy 
72730554d9SArtem B. Bityutskiy void
73e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f)
74730554d9SArtem B. Bityutskiy {
75730554d9SArtem B. Bityutskiy 	struct jffs2_node_frag *frag;
76730554d9SArtem B. Bityutskiy 	int bitched = 0;
77730554d9SArtem B. Bityutskiy 
78730554d9SArtem B. Bityutskiy 	for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
79730554d9SArtem B. Bityutskiy 		struct jffs2_full_dnode *fn = frag->node;
80730554d9SArtem B. Bityutskiy 
81730554d9SArtem B. Bityutskiy 		if (!fn || !fn->raw)
82730554d9SArtem B. Bityutskiy 			continue;
83730554d9SArtem B. Bityutskiy 
84730554d9SArtem B. Bityutskiy 		if (ref_flags(fn->raw) == REF_PRISTINE) {
85730554d9SArtem B. Bityutskiy 			if (fn->frags > 1) {
86e0c8e42fSArtem B. Bityutskiy 				JFFS2_ERROR("REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2.\n",
87730554d9SArtem B. Bityutskiy 					ref_offset(fn->raw), fn->frags);
88730554d9SArtem B. Bityutskiy 				bitched = 1;
89730554d9SArtem B. Bityutskiy 			}
90730554d9SArtem B. Bityutskiy 
91730554d9SArtem B. Bityutskiy 			/* A hole node which isn't multi-page should be garbage-collected
92730554d9SArtem B. Bityutskiy 			   and merged anyway, so we just check for the frag size here,
93730554d9SArtem B. Bityutskiy 			   rather than mucking around with actually reading the node
94730554d9SArtem B. Bityutskiy 			   and checking the compression type, which is the real way
95730554d9SArtem B. Bityutskiy 			   to tell a hole node. */
96730554d9SArtem B. Bityutskiy 			if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag)
97730554d9SArtem B. Bityutskiy 					&& frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) {
9881e39cf0SArtem B. Bityutskiy 				JFFS2_ERROR("REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2.\n",
9981e39cf0SArtem B. Bityutskiy 					ref_offset(fn->raw));
100730554d9SArtem B. Bityutskiy 				bitched = 1;
101730554d9SArtem B. Bityutskiy 			}
102730554d9SArtem B. Bityutskiy 
103730554d9SArtem B. Bityutskiy 			if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag)
104730554d9SArtem B. Bityutskiy 					&& frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) {
10581e39cf0SArtem B. Bityutskiy 				JFFS2_ERROR("REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2.\n",
106730554d9SArtem B. Bityutskiy 				       ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size);
107730554d9SArtem B. Bityutskiy 				bitched = 1;
108730554d9SArtem B. Bityutskiy 			}
109730554d9SArtem B. Bityutskiy 		}
110730554d9SArtem B. Bityutskiy 	}
111730554d9SArtem B. Bityutskiy 
112730554d9SArtem B. Bityutskiy 	if (bitched) {
113e0c8e42fSArtem B. Bityutskiy 		JFFS2_ERROR("fragtree is corrupted.\n");
114e0c8e42fSArtem B. Bityutskiy 		__jffs2_dbg_dump_fragtree_nolock(f);
115730554d9SArtem B. Bityutskiy 		BUG();
116730554d9SArtem B. Bityutskiy 	}
117730554d9SArtem B. Bityutskiy }
118730554d9SArtem B. Bityutskiy 
119730554d9SArtem B. Bityutskiy /*
120730554d9SArtem B. Bityutskiy  * Check if the flash contains all 0xFF before we start writing.
121730554d9SArtem B. Bityutskiy  */
122730554d9SArtem B. Bityutskiy void
123e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
124e0c8e42fSArtem B. Bityutskiy 				    uint32_t ofs, int len)
125730554d9SArtem B. Bityutskiy {
126730554d9SArtem B. Bityutskiy 	size_t retlen;
127730554d9SArtem B. Bityutskiy 	int ret, i;
128730554d9SArtem B. Bityutskiy 	unsigned char *buf;
129730554d9SArtem B. Bityutskiy 
130730554d9SArtem B. Bityutskiy 	buf = kmalloc(len, GFP_KERNEL);
131730554d9SArtem B. Bityutskiy 	if (!buf)
132730554d9SArtem B. Bityutskiy 		return;
133730554d9SArtem B. Bityutskiy 
134730554d9SArtem B. Bityutskiy 	ret = jffs2_flash_read(c, ofs, len, &retlen, buf);
135730554d9SArtem B. Bityutskiy 	if (ret || (retlen != len)) {
136e0c8e42fSArtem B. Bityutskiy 		JFFS2_WARNING("read %d bytes failed or short. ret %d, retlen %zd.\n",
137e0c8e42fSArtem B. Bityutskiy 				len, ret, retlen);
138730554d9SArtem B. Bityutskiy 		kfree(buf);
139730554d9SArtem B. Bityutskiy 		return;
140730554d9SArtem B. Bityutskiy 	}
141730554d9SArtem B. Bityutskiy 
142730554d9SArtem B. Bityutskiy 	ret = 0;
143730554d9SArtem B. Bityutskiy 	for (i = 0; i < len; i++)
144730554d9SArtem B. Bityutskiy 		if (buf[i] != 0xff)
145730554d9SArtem B. Bityutskiy 			ret = 1;
146730554d9SArtem B. Bityutskiy 
147730554d9SArtem B. Bityutskiy 	if (ret) {
14881e39cf0SArtem B. Bityutskiy 		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",
14981e39cf0SArtem B. Bityutskiy 			ofs, ofs + i);
150e0c8e42fSArtem B. Bityutskiy 		__jffs2_dbg_dump_buffer(buf, len, ofs);
151730554d9SArtem B. Bityutskiy 		kfree(buf);
152730554d9SArtem B. Bityutskiy 		BUG();
153730554d9SArtem B. Bityutskiy 	}
154730554d9SArtem B. Bityutskiy 
155730554d9SArtem B. Bityutskiy 	kfree(buf);
156730554d9SArtem B. Bityutskiy }
157730554d9SArtem B. Bityutskiy 
15885a62db6SDavid Woodhouse void __jffs2_dbg_superblock_counts(struct jffs2_sb_info *c)
15985a62db6SDavid Woodhouse {
16085a62db6SDavid Woodhouse 	struct jffs2_eraseblock *jeb;
16185a62db6SDavid Woodhouse 	uint32_t free = 0, dirty = 0, used = 0, wasted = 0,
16285a62db6SDavid Woodhouse 		erasing = 0, bad = 0, unchecked = 0;
16385a62db6SDavid Woodhouse 	int nr_counted = 0;
16485a62db6SDavid Woodhouse 	int dump = 0;
16585a62db6SDavid Woodhouse 
16685a62db6SDavid Woodhouse 	if (c->gcblock) {
16785a62db6SDavid Woodhouse 		nr_counted++;
16885a62db6SDavid Woodhouse 		free += c->gcblock->free_size;
16985a62db6SDavid Woodhouse 		dirty += c->gcblock->dirty_size;
17085a62db6SDavid Woodhouse 		used += c->gcblock->used_size;
17185a62db6SDavid Woodhouse 		wasted += c->gcblock->wasted_size;
17285a62db6SDavid Woodhouse 		unchecked += c->gcblock->unchecked_size;
17385a62db6SDavid Woodhouse 	}
17485a62db6SDavid Woodhouse 	if (c->nextblock) {
17585a62db6SDavid Woodhouse 		nr_counted++;
17685a62db6SDavid Woodhouse 		free += c->nextblock->free_size;
17785a62db6SDavid Woodhouse 		dirty += c->nextblock->dirty_size;
17885a62db6SDavid Woodhouse 		used += c->nextblock->used_size;
17985a62db6SDavid Woodhouse 		wasted += c->nextblock->wasted_size;
18085a62db6SDavid Woodhouse 		unchecked += c->nextblock->unchecked_size;
18185a62db6SDavid Woodhouse 	}
18285a62db6SDavid Woodhouse 	list_for_each_entry(jeb, &c->clean_list, list) {
18385a62db6SDavid Woodhouse 		nr_counted++;
18485a62db6SDavid Woodhouse 		free += jeb->free_size;
18585a62db6SDavid Woodhouse 		dirty += jeb->dirty_size;
18685a62db6SDavid Woodhouse 		used += jeb->used_size;
18785a62db6SDavid Woodhouse 		wasted += jeb->wasted_size;
18885a62db6SDavid Woodhouse 		unchecked += jeb->unchecked_size;
18985a62db6SDavid Woodhouse 	}
19085a62db6SDavid Woodhouse 	list_for_each_entry(jeb, &c->very_dirty_list, list) {
19185a62db6SDavid Woodhouse 		nr_counted++;
19285a62db6SDavid Woodhouse 		free += jeb->free_size;
19385a62db6SDavid Woodhouse 		dirty += jeb->dirty_size;
19485a62db6SDavid Woodhouse 		used += jeb->used_size;
19585a62db6SDavid Woodhouse 		wasted += jeb->wasted_size;
19685a62db6SDavid Woodhouse 		unchecked += jeb->unchecked_size;
19785a62db6SDavid Woodhouse 	}
19885a62db6SDavid Woodhouse 	list_for_each_entry(jeb, &c->dirty_list, list) {
19985a62db6SDavid Woodhouse 		nr_counted++;
20085a62db6SDavid Woodhouse 		free += jeb->free_size;
20185a62db6SDavid Woodhouse 		dirty += jeb->dirty_size;
20285a62db6SDavid Woodhouse 		used += jeb->used_size;
20385a62db6SDavid Woodhouse 		wasted += jeb->wasted_size;
20485a62db6SDavid Woodhouse 		unchecked += jeb->unchecked_size;
20585a62db6SDavid Woodhouse 	}
20685a62db6SDavid Woodhouse 	list_for_each_entry(jeb, &c->erasable_list, list) {
20785a62db6SDavid Woodhouse 		nr_counted++;
20885a62db6SDavid Woodhouse 		free += jeb->free_size;
20985a62db6SDavid Woodhouse 		dirty += jeb->dirty_size;
21085a62db6SDavid Woodhouse 		used += jeb->used_size;
21185a62db6SDavid Woodhouse 		wasted += jeb->wasted_size;
21285a62db6SDavid Woodhouse 		unchecked += jeb->unchecked_size;
21385a62db6SDavid Woodhouse 	}
21485a62db6SDavid Woodhouse 	list_for_each_entry(jeb, &c->erasable_pending_wbuf_list, list) {
21585a62db6SDavid Woodhouse 		nr_counted++;
21685a62db6SDavid Woodhouse 		free += jeb->free_size;
21785a62db6SDavid Woodhouse 		dirty += jeb->dirty_size;
21885a62db6SDavid Woodhouse 		used += jeb->used_size;
21985a62db6SDavid Woodhouse 		wasted += jeb->wasted_size;
22085a62db6SDavid Woodhouse 		unchecked += jeb->unchecked_size;
22185a62db6SDavid Woodhouse 	}
22285a62db6SDavid Woodhouse 	list_for_each_entry(jeb, &c->erase_pending_list, list) {
22385a62db6SDavid Woodhouse 		nr_counted++;
22485a62db6SDavid Woodhouse 		free += jeb->free_size;
22585a62db6SDavid Woodhouse 		dirty += jeb->dirty_size;
22685a62db6SDavid Woodhouse 		used += jeb->used_size;
22785a62db6SDavid Woodhouse 		wasted += jeb->wasted_size;
22885a62db6SDavid Woodhouse 		unchecked += jeb->unchecked_size;
22985a62db6SDavid Woodhouse 	}
23085a62db6SDavid Woodhouse 	list_for_each_entry(jeb, &c->free_list, list) {
23185a62db6SDavid Woodhouse 		nr_counted++;
23285a62db6SDavid Woodhouse 		free += jeb->free_size;
23385a62db6SDavid Woodhouse 		dirty += jeb->dirty_size;
23485a62db6SDavid Woodhouse 		used += jeb->used_size;
23585a62db6SDavid Woodhouse 		wasted += jeb->wasted_size;
23685a62db6SDavid Woodhouse 		unchecked += jeb->unchecked_size;
23785a62db6SDavid Woodhouse 	}
23885a62db6SDavid Woodhouse 	list_for_each_entry(jeb, &c->bad_used_list, list) {
23985a62db6SDavid Woodhouse 		nr_counted++;
24085a62db6SDavid Woodhouse 		free += jeb->free_size;
24185a62db6SDavid Woodhouse 		dirty += jeb->dirty_size;
24285a62db6SDavid Woodhouse 		used += jeb->used_size;
24385a62db6SDavid Woodhouse 		wasted += jeb->wasted_size;
24485a62db6SDavid Woodhouse 		unchecked += jeb->unchecked_size;
24585a62db6SDavid Woodhouse 	}
24685a62db6SDavid Woodhouse 
24785a62db6SDavid Woodhouse 	list_for_each_entry(jeb, &c->erasing_list, list) {
24885a62db6SDavid Woodhouse 		nr_counted++;
24985a62db6SDavid Woodhouse 		erasing += c->sector_size;
25085a62db6SDavid Woodhouse 	}
251e2bc322bSDavid Woodhouse 	list_for_each_entry(jeb, &c->erase_checking_list, list) {
252e2bc322bSDavid Woodhouse 		nr_counted++;
253e2bc322bSDavid Woodhouse 		erasing += c->sector_size;
254e2bc322bSDavid Woodhouse 	}
25585a62db6SDavid Woodhouse 	list_for_each_entry(jeb, &c->erase_complete_list, list) {
25685a62db6SDavid Woodhouse 		nr_counted++;
25785a62db6SDavid Woodhouse 		erasing += c->sector_size;
25885a62db6SDavid Woodhouse 	}
25985a62db6SDavid Woodhouse 	list_for_each_entry(jeb, &c->bad_list, list) {
26085a62db6SDavid Woodhouse 		nr_counted++;
26185a62db6SDavid Woodhouse 		bad += c->sector_size;
26285a62db6SDavid Woodhouse 	}
26385a62db6SDavid Woodhouse 
26485a62db6SDavid Woodhouse #define check(sz)							\
265da320f05SJoe Perches do {									\
26685a62db6SDavid Woodhouse 	if (sz != c->sz##_size) {					\
267da320f05SJoe Perches 		pr_warn("%s_size mismatch counted 0x%x, c->%s_size 0x%x\n", \
268da320f05SJoe Perches 			#sz, #sz, sz, c->sz##_size);			\
26985a62db6SDavid Woodhouse 		dump = 1;						\
270da320f05SJoe Perches 	}								\
271da320f05SJoe Perches } while (0)
272da320f05SJoe Perches 
27385a62db6SDavid Woodhouse 	check(free);
27485a62db6SDavid Woodhouse 	check(dirty);
27585a62db6SDavid Woodhouse 	check(used);
27685a62db6SDavid Woodhouse 	check(wasted);
27785a62db6SDavid Woodhouse 	check(unchecked);
27885a62db6SDavid Woodhouse 	check(bad);
27985a62db6SDavid Woodhouse 	check(erasing);
280da320f05SJoe Perches 
28185a62db6SDavid Woodhouse #undef check
28285a62db6SDavid Woodhouse 
28385a62db6SDavid Woodhouse 	if (nr_counted != c->nr_blocks) {
284da320f05SJoe Perches 		pr_warn("%s counted only 0x%x blocks of 0x%x. Where are the others?\n",
28585a62db6SDavid Woodhouse 			__func__, nr_counted, c->nr_blocks);
28685a62db6SDavid Woodhouse 		dump = 1;
28785a62db6SDavid Woodhouse 	}
28885a62db6SDavid Woodhouse 
28985a62db6SDavid Woodhouse 	if (dump) {
29085a62db6SDavid Woodhouse 		__jffs2_dbg_dump_block_lists_nolock(c);
29185a62db6SDavid Woodhouse 		BUG();
29285a62db6SDavid Woodhouse 	}
29385a62db6SDavid Woodhouse }
29485a62db6SDavid Woodhouse 
295730554d9SArtem B. Bityutskiy /*
296730554d9SArtem B. Bityutskiy  * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
297730554d9SArtem B. Bityutskiy  */
298730554d9SArtem B. Bityutskiy void
299e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c,
300e0c8e42fSArtem B. Bityutskiy 				struct jffs2_eraseblock *jeb)
301e0c8e42fSArtem B. Bityutskiy {
302e0c8e42fSArtem B. Bityutskiy 	spin_lock(&c->erase_completion_lock);
303e0c8e42fSArtem B. Bityutskiy 	__jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
304e0c8e42fSArtem B. Bityutskiy 	spin_unlock(&c->erase_completion_lock);
305e0c8e42fSArtem B. Bityutskiy }
306e0c8e42fSArtem B. Bityutskiy 
307e0c8e42fSArtem B. Bityutskiy void
308e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
309e0c8e42fSArtem B. Bityutskiy 				       struct jffs2_eraseblock *jeb)
310730554d9SArtem B. Bityutskiy {
311730554d9SArtem B. Bityutskiy 	uint32_t my_used_size = 0;
312730554d9SArtem B. Bityutskiy 	uint32_t my_unchecked_size = 0;
313730554d9SArtem B. Bityutskiy 	uint32_t my_dirty_size = 0;
314730554d9SArtem B. Bityutskiy 	struct jffs2_raw_node_ref *ref2 = jeb->first_node;
315730554d9SArtem B. Bityutskiy 
316730554d9SArtem B. Bityutskiy 	while (ref2) {
317730554d9SArtem B. Bityutskiy 		uint32_t totlen = ref_totlen(c, jeb, ref2);
318730554d9SArtem B. Bityutskiy 
319abb536e7SKyungmin Park 		if (ref_offset(ref2) < jeb->offset ||
320abb536e7SKyungmin Park 				ref_offset(ref2) > jeb->offset + c->sector_size) {
321e0c8e42fSArtem B. Bityutskiy 			JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.\n",
322730554d9SArtem B. Bityutskiy 				ref_offset(ref2), jeb->offset);
323e0c8e42fSArtem B. Bityutskiy 			goto error;
324730554d9SArtem B. Bityutskiy 
325730554d9SArtem B. Bityutskiy 		}
326730554d9SArtem B. Bityutskiy 		if (ref_flags(ref2) == REF_UNCHECKED)
327730554d9SArtem B. Bityutskiy 			my_unchecked_size += totlen;
328730554d9SArtem B. Bityutskiy 		else if (!ref_obsolete(ref2))
329730554d9SArtem B. Bityutskiy 			my_used_size += totlen;
330730554d9SArtem B. Bityutskiy 		else
331730554d9SArtem B. Bityutskiy 			my_dirty_size += totlen;
332730554d9SArtem B. Bityutskiy 
33399988f7bSDavid Woodhouse 		if ((!ref_next(ref2)) != (ref2 == jeb->last_node)) {
33499988f7bSDavid Woodhouse 			JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next at %#08x (mem %p), last_node is at %#08x (mem %p).\n",
33599988f7bSDavid Woodhouse 				    ref_offset(ref2), ref2, ref_offset(ref_next(ref2)), ref_next(ref2),
336730554d9SArtem B. Bityutskiy 				    ref_offset(jeb->last_node), jeb->last_node);
337e0c8e42fSArtem B. Bityutskiy 			goto error;
338730554d9SArtem B. Bityutskiy 		}
33999988f7bSDavid Woodhouse 		ref2 = ref_next(ref2);
340730554d9SArtem B. Bityutskiy 	}
341730554d9SArtem B. Bityutskiy 
342730554d9SArtem B. Bityutskiy 	if (my_used_size != jeb->used_size) {
343e0c8e42fSArtem B. Bityutskiy 		JFFS2_ERROR("Calculated used size %#08x != stored used size %#08x.\n",
344730554d9SArtem B. Bityutskiy 			my_used_size, jeb->used_size);
345e0c8e42fSArtem B. Bityutskiy 		goto error;
346730554d9SArtem B. Bityutskiy 	}
347730554d9SArtem B. Bityutskiy 
348730554d9SArtem B. Bityutskiy 	if (my_unchecked_size != jeb->unchecked_size) {
349e0c8e42fSArtem B. Bityutskiy 		JFFS2_ERROR("Calculated unchecked size %#08x != stored unchecked size %#08x.\n",
350730554d9SArtem B. Bityutskiy 			my_unchecked_size, jeb->unchecked_size);
351e0c8e42fSArtem B. Bityutskiy 		goto error;
352730554d9SArtem B. Bityutskiy 	}
353730554d9SArtem B. Bityutskiy 
354e0c8e42fSArtem B. Bityutskiy #if 0
355e0c8e42fSArtem B. Bityutskiy 	/* This should work when we implement ref->__totlen elemination */
356730554d9SArtem B. Bityutskiy 	if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) {
357e0c8e42fSArtem B. Bityutskiy 		JFFS2_ERROR("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n",
358730554d9SArtem B. Bityutskiy 			my_dirty_size, jeb->dirty_size + jeb->wasted_size);
359e0c8e42fSArtem B. Bityutskiy 		goto error;
360730554d9SArtem B. Bityutskiy 	}
361730554d9SArtem B. Bityutskiy 
362730554d9SArtem B. Bityutskiy 	if (jeb->free_size == 0
363730554d9SArtem B. Bityutskiy 		&& my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) {
364e0c8e42fSArtem B. Bityutskiy 		JFFS2_ERROR("The sum of all nodes in block (%#x) != size of block (%#x)\n",
365730554d9SArtem B. Bityutskiy 			my_used_size + my_unchecked_size + my_dirty_size,
366730554d9SArtem B. Bityutskiy 			c->sector_size);
367e0c8e42fSArtem B. Bityutskiy 		goto error;
368730554d9SArtem B. Bityutskiy 	}
369e0c8e42fSArtem B. Bityutskiy #endif
370730554d9SArtem B. Bityutskiy 
37185a62db6SDavid Woodhouse 	if (!(c->flags & (JFFS2_SB_FLAG_BUILDING|JFFS2_SB_FLAG_SCANNING)))
37285a62db6SDavid Woodhouse 		__jffs2_dbg_superblock_counts(c);
37385a62db6SDavid Woodhouse 
374e0c8e42fSArtem B. Bityutskiy 	return;
375e0c8e42fSArtem B. Bityutskiy 
376e0c8e42fSArtem B. Bityutskiy error:
377e0c8e42fSArtem B. Bityutskiy 	__jffs2_dbg_dump_node_refs_nolock(c, jeb);
378e0c8e42fSArtem B. Bityutskiy 	__jffs2_dbg_dump_jeb_nolock(jeb);
379e0c8e42fSArtem B. Bityutskiy 	__jffs2_dbg_dump_block_lists_nolock(c);
380e0c8e42fSArtem B. Bityutskiy 	BUG();
381e0c8e42fSArtem B. Bityutskiy 
382e0c8e42fSArtem B. Bityutskiy }
383e0c8e42fSArtem B. Bityutskiy #endif /* JFFS2_DBG_PARANOIA_CHECKS */
384e0c8e42fSArtem B. Bityutskiy 
385e0c8e42fSArtem B. Bityutskiy #if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS)
386730554d9SArtem B. Bityutskiy /*
387730554d9SArtem B. Bityutskiy  * Dump the node_refs of the 'jeb' JFFS2 eraseblock.
388730554d9SArtem B. Bityutskiy  */
389730554d9SArtem B. Bityutskiy void
390e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c,
391e0c8e42fSArtem B. Bityutskiy 			   struct jffs2_eraseblock *jeb)
392e0c8e42fSArtem B. Bityutskiy {
393e0c8e42fSArtem B. Bityutskiy 	spin_lock(&c->erase_completion_lock);
394e0c8e42fSArtem B. Bityutskiy 	__jffs2_dbg_dump_node_refs_nolock(c, jeb);
395e0c8e42fSArtem B. Bityutskiy 	spin_unlock(&c->erase_completion_lock);
396e0c8e42fSArtem B. Bityutskiy }
397e0c8e42fSArtem B. Bityutskiy 
398e0c8e42fSArtem B. Bityutskiy void
399e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c,
400e0c8e42fSArtem B. Bityutskiy 				  struct jffs2_eraseblock *jeb)
401730554d9SArtem B. Bityutskiy {
402730554d9SArtem B. Bityutskiy 	struct jffs2_raw_node_ref *ref;
403730554d9SArtem B. Bityutskiy 	int i = 0;
404730554d9SArtem B. Bityutskiy 
40581e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG_MSG_PREFIX " Dump node_refs of the eraseblock %#08x\n", jeb->offset);
406730554d9SArtem B. Bityutskiy 	if (!jeb->first_node) {
40781e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG_MSG_PREFIX " no nodes in the eraseblock %#08x\n", jeb->offset);
408730554d9SArtem B. Bityutskiy 		return;
409730554d9SArtem B. Bityutskiy 	}
410730554d9SArtem B. Bityutskiy 
41181e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG);
41299988f7bSDavid Woodhouse 	for (ref = jeb->first_node; ; ref = ref_next(ref)) {
41327e6b8e3SDavid Woodhouse 		printk("%#08x", ref_offset(ref));
41427e6b8e3SDavid Woodhouse #ifdef TEST_TOTLEN
41527e6b8e3SDavid Woodhouse 		printk("(%x)", ref->__totlen);
41627e6b8e3SDavid Woodhouse #endif
41799988f7bSDavid Woodhouse 		if (ref_next(ref))
418730554d9SArtem B. Bityutskiy 			printk("->");
419730554d9SArtem B. Bityutskiy 		else
420730554d9SArtem B. Bityutskiy 			break;
421730554d9SArtem B. Bityutskiy 		if (++i == 4) {
422730554d9SArtem B. Bityutskiy 			i = 0;
42381e39cf0SArtem B. Bityutskiy 			printk("\n" JFFS2_DBG);
424730554d9SArtem B. Bityutskiy 		}
425730554d9SArtem B. Bityutskiy 	}
426730554d9SArtem B. Bityutskiy 	printk("\n");
427730554d9SArtem B. Bityutskiy }
428730554d9SArtem B. Bityutskiy 
429e0c8e42fSArtem B. Bityutskiy /*
430e0c8e42fSArtem B. Bityutskiy  * Dump an eraseblock's space accounting.
431e0c8e42fSArtem B. Bityutskiy  */
432730554d9SArtem B. Bityutskiy void
433e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
434730554d9SArtem B. Bityutskiy {
435e0c8e42fSArtem B. Bityutskiy 	spin_lock(&c->erase_completion_lock);
436e0c8e42fSArtem B. Bityutskiy 	__jffs2_dbg_dump_jeb_nolock(jeb);
437e0c8e42fSArtem B. Bityutskiy 	spin_unlock(&c->erase_completion_lock);
438e0c8e42fSArtem B. Bityutskiy }
439e0c8e42fSArtem B. Bityutskiy 
440e0c8e42fSArtem B. Bityutskiy void
441e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb)
442e0c8e42fSArtem B. Bityutskiy {
443e0c8e42fSArtem B. Bityutskiy 	if (!jeb)
444e0c8e42fSArtem B. Bityutskiy 		return;
445e0c8e42fSArtem B. Bityutskiy 
44681e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG_MSG_PREFIX " dump space accounting for the eraseblock at %#08x:\n",
447e0c8e42fSArtem B. Bityutskiy 			jeb->offset);
448e0c8e42fSArtem B. Bityutskiy 
44981e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "used_size: %#08x\n",		jeb->used_size);
45081e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "dirty_size: %#08x\n",		jeb->dirty_size);
45181e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "wasted_size: %#08x\n",	jeb->wasted_size);
45281e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "unchecked_size: %#08x\n",	jeb->unchecked_size);
45381e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "free_size: %#08x\n",		jeb->free_size);
454e0c8e42fSArtem B. Bityutskiy }
455e0c8e42fSArtem B. Bityutskiy 
456e0c8e42fSArtem B. Bityutskiy void
457e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c)
458e0c8e42fSArtem B. Bityutskiy {
459e0c8e42fSArtem B. Bityutskiy 	spin_lock(&c->erase_completion_lock);
460e0c8e42fSArtem B. Bityutskiy 	__jffs2_dbg_dump_block_lists_nolock(c);
461e0c8e42fSArtem B. Bityutskiy 	spin_unlock(&c->erase_completion_lock);
462e0c8e42fSArtem B. Bityutskiy }
463e0c8e42fSArtem B. Bityutskiy 
464e0c8e42fSArtem B. Bityutskiy void
465e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c)
466e0c8e42fSArtem B. Bityutskiy {
46781e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG_MSG_PREFIX " dump JFFS2 blocks lists:\n");
468e0c8e42fSArtem B. Bityutskiy 
46981e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "flash_size: %#08x\n",		c->flash_size);
47081e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "used_size: %#08x\n",		c->used_size);
47181e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "dirty_size: %#08x\n",		c->dirty_size);
47281e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "wasted_size: %#08x\n",	c->wasted_size);
47381e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "unchecked_size: %#08x\n",	c->unchecked_size);
47481e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "free_size: %#08x\n",		c->free_size);
47581e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "erasing_size: %#08x\n",	c->erasing_size);
47681e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "bad_size: %#08x\n",		c->bad_size);
47781e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "sector_size: %#08x\n",	c->sector_size);
47881e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "jffs2_reserved_blocks size: %#08x\n",
479730554d9SArtem B. Bityutskiy 				c->sector_size * c->resv_blocks_write);
480730554d9SArtem B. Bityutskiy 
481730554d9SArtem B. Bityutskiy 	if (c->nextblock)
48281e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
483730554d9SArtem B. Bityutskiy 			c->nextblock->offset, c->nextblock->used_size,
484730554d9SArtem B. Bityutskiy 			c->nextblock->dirty_size, c->nextblock->wasted_size,
485730554d9SArtem B. Bityutskiy 			c->nextblock->unchecked_size, c->nextblock->free_size);
486730554d9SArtem B. Bityutskiy 	else
48781e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "nextblock: NULL\n");
488730554d9SArtem B. Bityutskiy 
489730554d9SArtem B. Bityutskiy 	if (c->gcblock)
49081e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
491730554d9SArtem B. Bityutskiy 			c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size,
492730554d9SArtem B. Bityutskiy 			c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
493730554d9SArtem B. Bityutskiy 	else
49481e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "gcblock: NULL\n");
495730554d9SArtem B. Bityutskiy 
496730554d9SArtem B. Bityutskiy 	if (list_empty(&c->clean_list)) {
49781e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "clean_list: empty\n");
498730554d9SArtem B. Bityutskiy 	} else {
499730554d9SArtem B. Bityutskiy 		struct list_head *this;
500730554d9SArtem B. Bityutskiy 		int numblocks = 0;
501730554d9SArtem B. Bityutskiy 		uint32_t dirty = 0;
502730554d9SArtem B. Bityutskiy 
503730554d9SArtem B. Bityutskiy 		list_for_each(this, &c->clean_list) {
504730554d9SArtem B. Bityutskiy 			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
505730554d9SArtem B. Bityutskiy 			numblocks ++;
506730554d9SArtem B. Bityutskiy 			dirty += jeb->wasted_size;
507730554d9SArtem B. Bityutskiy 			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
50881e39cf0SArtem B. Bityutskiy 				printk(JFFS2_DBG "clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
509730554d9SArtem B. Bityutskiy 					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
510730554d9SArtem B. Bityutskiy 					jeb->unchecked_size, jeb->free_size);
511730554d9SArtem B. Bityutskiy 			}
512730554d9SArtem B. Bityutskiy 		}
513730554d9SArtem B. Bityutskiy 
51481e39cf0SArtem B. Bityutskiy 		printk (JFFS2_DBG "Contains %d blocks with total wasted size %u, average wasted size: %u\n",
515730554d9SArtem B. Bityutskiy 			numblocks, dirty, dirty / numblocks);
516730554d9SArtem B. Bityutskiy 	}
517730554d9SArtem B. Bityutskiy 
518730554d9SArtem B. Bityutskiy 	if (list_empty(&c->very_dirty_list)) {
51981e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "very_dirty_list: empty\n");
520730554d9SArtem B. Bityutskiy 	} else {
521730554d9SArtem B. Bityutskiy 		struct list_head *this;
522730554d9SArtem B. Bityutskiy 		int numblocks = 0;
523730554d9SArtem B. Bityutskiy 		uint32_t dirty = 0;
524730554d9SArtem B. Bityutskiy 
525730554d9SArtem B. Bityutskiy 		list_for_each(this, &c->very_dirty_list) {
526730554d9SArtem B. Bityutskiy 			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
527730554d9SArtem B. Bityutskiy 
528730554d9SArtem B. Bityutskiy 			numblocks ++;
529730554d9SArtem B. Bityutskiy 			dirty += jeb->dirty_size;
530730554d9SArtem B. Bityutskiy 			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
53181e39cf0SArtem B. Bityutskiy 				printk(JFFS2_DBG "very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
532730554d9SArtem B. Bityutskiy 					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
533730554d9SArtem B. Bityutskiy 					jeb->unchecked_size, jeb->free_size);
534730554d9SArtem B. Bityutskiy 			}
535730554d9SArtem B. Bityutskiy 		}
536730554d9SArtem B. Bityutskiy 
53781e39cf0SArtem B. Bityutskiy 		printk (JFFS2_DBG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
538730554d9SArtem B. Bityutskiy 			numblocks, dirty, dirty / numblocks);
539730554d9SArtem B. Bityutskiy 	}
540730554d9SArtem B. Bityutskiy 
541730554d9SArtem B. Bityutskiy 	if (list_empty(&c->dirty_list)) {
54281e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "dirty_list: empty\n");
543730554d9SArtem B. Bityutskiy 	} else {
544730554d9SArtem B. Bityutskiy 		struct list_head *this;
545730554d9SArtem B. Bityutskiy 		int numblocks = 0;
546730554d9SArtem B. Bityutskiy 		uint32_t dirty = 0;
547730554d9SArtem B. Bityutskiy 
548730554d9SArtem B. Bityutskiy 		list_for_each(this, &c->dirty_list) {
549730554d9SArtem B. Bityutskiy 			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
550730554d9SArtem B. Bityutskiy 
551730554d9SArtem B. Bityutskiy 			numblocks ++;
552730554d9SArtem B. Bityutskiy 			dirty += jeb->dirty_size;
553730554d9SArtem B. Bityutskiy 			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
55481e39cf0SArtem B. Bityutskiy 				printk(JFFS2_DBG "dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
555730554d9SArtem B. Bityutskiy 					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
556730554d9SArtem B. Bityutskiy 					jeb->unchecked_size, jeb->free_size);
557730554d9SArtem B. Bityutskiy 			}
558730554d9SArtem B. Bityutskiy 		}
559730554d9SArtem B. Bityutskiy 
56081e39cf0SArtem B. Bityutskiy 		printk (JFFS2_DBG "contains %d blocks with total dirty size %u, average dirty size: %u\n",
561730554d9SArtem B. Bityutskiy 			numblocks, dirty, dirty / numblocks);
562730554d9SArtem B. Bityutskiy 	}
563730554d9SArtem B. Bityutskiy 
564730554d9SArtem B. Bityutskiy 	if (list_empty(&c->erasable_list)) {
56581e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "erasable_list: empty\n");
566730554d9SArtem B. Bityutskiy 	} else {
567730554d9SArtem B. Bityutskiy 		struct list_head *this;
568730554d9SArtem B. Bityutskiy 
569730554d9SArtem B. Bityutskiy 		list_for_each(this, &c->erasable_list) {
570730554d9SArtem B. Bityutskiy 			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
571730554d9SArtem B. Bityutskiy 
572730554d9SArtem B. Bityutskiy 			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
57381e39cf0SArtem B. Bityutskiy 				printk(JFFS2_DBG "erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
574730554d9SArtem B. Bityutskiy 					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
575730554d9SArtem B. Bityutskiy 					jeb->unchecked_size, jeb->free_size);
576730554d9SArtem B. Bityutskiy 			}
577730554d9SArtem B. Bityutskiy 		}
578730554d9SArtem B. Bityutskiy 	}
579730554d9SArtem B. Bityutskiy 
580730554d9SArtem B. Bityutskiy 	if (list_empty(&c->erasing_list)) {
58181e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "erasing_list: empty\n");
582730554d9SArtem B. Bityutskiy 	} else {
583730554d9SArtem B. Bityutskiy 		struct list_head *this;
584730554d9SArtem B. Bityutskiy 
585730554d9SArtem B. Bityutskiy 		list_for_each(this, &c->erasing_list) {
586730554d9SArtem B. Bityutskiy 			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
587730554d9SArtem B. Bityutskiy 
588730554d9SArtem B. Bityutskiy 			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
58981e39cf0SArtem B. Bityutskiy 				printk(JFFS2_DBG "erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
590730554d9SArtem B. Bityutskiy 					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
591730554d9SArtem B. Bityutskiy 					jeb->unchecked_size, jeb->free_size);
592730554d9SArtem B. Bityutskiy 			}
593730554d9SArtem B. Bityutskiy 		}
594730554d9SArtem B. Bityutskiy 	}
595e2bc322bSDavid Woodhouse 	if (list_empty(&c->erase_checking_list)) {
596e2bc322bSDavid Woodhouse 		printk(JFFS2_DBG "erase_checking_list: empty\n");
597e2bc322bSDavid Woodhouse 	} else {
598e2bc322bSDavid Woodhouse 		struct list_head *this;
599e2bc322bSDavid Woodhouse 
600e2bc322bSDavid Woodhouse 		list_for_each(this, &c->erase_checking_list) {
601e2bc322bSDavid Woodhouse 			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
602e2bc322bSDavid Woodhouse 
603e2bc322bSDavid Woodhouse 			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
604e2bc322bSDavid Woodhouse 				printk(JFFS2_DBG "erase_checking_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
605e2bc322bSDavid Woodhouse 					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
606e2bc322bSDavid Woodhouse 					jeb->unchecked_size, jeb->free_size);
607e2bc322bSDavid Woodhouse 			}
608e2bc322bSDavid Woodhouse 		}
609e2bc322bSDavid Woodhouse 	}
610730554d9SArtem B. Bityutskiy 
611730554d9SArtem B. Bityutskiy 	if (list_empty(&c->erase_pending_list)) {
61281e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "erase_pending_list: empty\n");
613730554d9SArtem B. Bityutskiy 	} else {
614730554d9SArtem B. Bityutskiy 		struct list_head *this;
615730554d9SArtem B. Bityutskiy 
616730554d9SArtem B. Bityutskiy 		list_for_each(this, &c->erase_pending_list) {
617730554d9SArtem B. Bityutskiy 			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
618730554d9SArtem B. Bityutskiy 
619730554d9SArtem B. Bityutskiy 			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
62081e39cf0SArtem B. Bityutskiy 				printk(JFFS2_DBG "erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
621730554d9SArtem B. Bityutskiy 					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
622730554d9SArtem B. Bityutskiy 					jeb->unchecked_size, jeb->free_size);
623730554d9SArtem B. Bityutskiy 			}
624730554d9SArtem B. Bityutskiy 		}
625730554d9SArtem B. Bityutskiy 	}
626730554d9SArtem B. Bityutskiy 
627730554d9SArtem B. Bityutskiy 	if (list_empty(&c->erasable_pending_wbuf_list)) {
62881e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "erasable_pending_wbuf_list: empty\n");
629730554d9SArtem B. Bityutskiy 	} else {
630730554d9SArtem B. Bityutskiy 		struct list_head *this;
631730554d9SArtem B. Bityutskiy 
632730554d9SArtem B. Bityutskiy 		list_for_each(this, &c->erasable_pending_wbuf_list) {
633730554d9SArtem B. Bityutskiy 			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
634730554d9SArtem B. Bityutskiy 
635730554d9SArtem B. Bityutskiy 			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
63681e39cf0SArtem B. Bityutskiy 				printk(JFFS2_DBG "erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
637730554d9SArtem B. Bityutskiy 					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
638730554d9SArtem B. Bityutskiy 					jeb->unchecked_size, jeb->free_size);
639730554d9SArtem B. Bityutskiy 			}
640730554d9SArtem B. Bityutskiy 		}
641730554d9SArtem B. Bityutskiy 	}
642730554d9SArtem B. Bityutskiy 
643730554d9SArtem B. Bityutskiy 	if (list_empty(&c->free_list)) {
64481e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "free_list: empty\n");
645730554d9SArtem B. Bityutskiy 	} else {
646730554d9SArtem B. Bityutskiy 		struct list_head *this;
647730554d9SArtem B. Bityutskiy 
648730554d9SArtem B. Bityutskiy 		list_for_each(this, &c->free_list) {
649730554d9SArtem B. Bityutskiy 			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
650730554d9SArtem B. Bityutskiy 
651730554d9SArtem B. Bityutskiy 			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
65281e39cf0SArtem B. Bityutskiy 				printk(JFFS2_DBG "free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
653730554d9SArtem B. Bityutskiy 					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
654730554d9SArtem B. Bityutskiy 					jeb->unchecked_size, jeb->free_size);
655730554d9SArtem B. Bityutskiy 			}
656730554d9SArtem B. Bityutskiy 		}
657730554d9SArtem B. Bityutskiy 	}
658730554d9SArtem B. Bityutskiy 
659730554d9SArtem B. Bityutskiy 	if (list_empty(&c->bad_list)) {
66081e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "bad_list: empty\n");
661730554d9SArtem B. Bityutskiy 	} else {
662730554d9SArtem B. Bityutskiy 		struct list_head *this;
663730554d9SArtem B. Bityutskiy 
664730554d9SArtem B. Bityutskiy 		list_for_each(this, &c->bad_list) {
665730554d9SArtem B. Bityutskiy 			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
666730554d9SArtem B. Bityutskiy 
667730554d9SArtem B. Bityutskiy 			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
66881e39cf0SArtem B. Bityutskiy 				printk(JFFS2_DBG "bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
669730554d9SArtem B. Bityutskiy 					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
670730554d9SArtem B. Bityutskiy 					jeb->unchecked_size, jeb->free_size);
671730554d9SArtem B. Bityutskiy 			}
672730554d9SArtem B. Bityutskiy 		}
673730554d9SArtem B. Bityutskiy 	}
674730554d9SArtem B. Bityutskiy 
675730554d9SArtem B. Bityutskiy 	if (list_empty(&c->bad_used_list)) {
67681e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "bad_used_list: empty\n");
677730554d9SArtem B. Bityutskiy 	} else {
678730554d9SArtem B. Bityutskiy 		struct list_head *this;
679730554d9SArtem B. Bityutskiy 
680730554d9SArtem B. Bityutskiy 		list_for_each(this, &c->bad_used_list) {
681730554d9SArtem B. Bityutskiy 			struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
682730554d9SArtem B. Bityutskiy 
683730554d9SArtem B. Bityutskiy 			if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
68481e39cf0SArtem B. Bityutskiy 				printk(JFFS2_DBG "bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
685730554d9SArtem B. Bityutskiy 					jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
686730554d9SArtem B. Bityutskiy 					jeb->unchecked_size, jeb->free_size);
687730554d9SArtem B. Bityutskiy 			}
688730554d9SArtem B. Bityutskiy 		}
689730554d9SArtem B. Bityutskiy 	}
690730554d9SArtem B. Bityutskiy }
691730554d9SArtem B. Bityutskiy 
692730554d9SArtem B. Bityutskiy void
693e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f)
694e0c8e42fSArtem B. Bityutskiy {
695ced22070SDavid Woodhouse 	mutex_lock(&f->sem);
696e0c8e42fSArtem B. Bityutskiy 	jffs2_dbg_dump_fragtree_nolock(f);
697ced22070SDavid Woodhouse 	mutex_unlock(&f->sem);
698e0c8e42fSArtem B. Bityutskiy }
699e0c8e42fSArtem B. Bityutskiy 
700e0c8e42fSArtem B. Bityutskiy void
701e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f)
702730554d9SArtem B. Bityutskiy {
703730554d9SArtem B. Bityutskiy 	struct jffs2_node_frag *this = frag_first(&f->fragtree);
704730554d9SArtem B. Bityutskiy 	uint32_t lastofs = 0;
705730554d9SArtem B. Bityutskiy 	int buggy = 0;
706730554d9SArtem B. Bityutskiy 
70781e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG_MSG_PREFIX " dump fragtree of ino #%u\n", f->inocache->ino);
708730554d9SArtem B. Bityutskiy 	while(this) {
709730554d9SArtem B. Bityutskiy 		if (this->node)
71081e39cf0SArtem B. Bityutskiy 			printk(JFFS2_DBG "frag %#04x-%#04x: %#08x(%d) on flash (*%p), left (%p), right (%p), parent (%p)\n",
711730554d9SArtem B. Bityutskiy 				this->ofs, this->ofs+this->size, ref_offset(this->node->raw),
712730554d9SArtem B. Bityutskiy 				ref_flags(this->node->raw), this, frag_left(this), frag_right(this),
713730554d9SArtem B. Bityutskiy 				frag_parent(this));
714730554d9SArtem B. Bityutskiy 		else
71581e39cf0SArtem B. Bityutskiy 			printk(JFFS2_DBG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n",
716730554d9SArtem B. Bityutskiy 				this->ofs, this->ofs+this->size, this, frag_left(this),
717730554d9SArtem B. Bityutskiy 				frag_right(this), frag_parent(this));
718730554d9SArtem B. Bityutskiy 		if (this->ofs != lastofs)
719730554d9SArtem B. Bityutskiy 			buggy = 1;
720730554d9SArtem B. Bityutskiy 		lastofs = this->ofs + this->size;
721730554d9SArtem B. Bityutskiy 		this = frag_next(this);
722730554d9SArtem B. Bityutskiy 	}
723730554d9SArtem B. Bityutskiy 
724730554d9SArtem B. Bityutskiy 	if (f->metadata)
72581e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
726730554d9SArtem B. Bityutskiy 
727730554d9SArtem B. Bityutskiy 	if (buggy) {
728e0c8e42fSArtem B. Bityutskiy 		JFFS2_ERROR("frag tree got a hole in it.\n");
729730554d9SArtem B. Bityutskiy 		BUG();
730730554d9SArtem B. Bityutskiy 	}
731730554d9SArtem B. Bityutskiy }
732730554d9SArtem B. Bityutskiy 
733e0c8e42fSArtem B. Bityutskiy #define JFFS2_BUFDUMP_BYTES_PER_LINE	32
734730554d9SArtem B. Bityutskiy void
735e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs)
736730554d9SArtem B. Bityutskiy {
737e0c8e42fSArtem B. Bityutskiy 	int skip;
738e0c8e42fSArtem B. Bityutskiy 	int i;
739e0c8e42fSArtem B. Bityutskiy 
74081e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG_MSG_PREFIX " dump from offset %#08x to offset %#08x (%x bytes).\n",
741e0c8e42fSArtem B. Bityutskiy 		offs, offs + len, len);
742e0c8e42fSArtem B. Bityutskiy 	i = skip = offs % JFFS2_BUFDUMP_BYTES_PER_LINE;
743e0c8e42fSArtem B. Bityutskiy 	offs = offs & ~(JFFS2_BUFDUMP_BYTES_PER_LINE - 1);
744e0c8e42fSArtem B. Bityutskiy 
745e0c8e42fSArtem B. Bityutskiy 	if (skip != 0)
74681e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "%#08x: ", offs);
747e0c8e42fSArtem B. Bityutskiy 
748e0c8e42fSArtem B. Bityutskiy 	while (skip--)
749e0c8e42fSArtem B. Bityutskiy 		printk("   ");
750730554d9SArtem B. Bityutskiy 
751730554d9SArtem B. Bityutskiy 	while (i < len) {
752e0c8e42fSArtem B. Bityutskiy 		if ((i % JFFS2_BUFDUMP_BYTES_PER_LINE) == 0 && i != len -1) {
753e0c8e42fSArtem B. Bityutskiy 			if (i != 0)
754e0c8e42fSArtem B. Bityutskiy 				printk("\n");
755e0c8e42fSArtem B. Bityutskiy 			offs += JFFS2_BUFDUMP_BYTES_PER_LINE;
75681e39cf0SArtem B. Bityutskiy 			printk(JFFS2_DBG "%0#8x: ", offs);
757730554d9SArtem B. Bityutskiy 		}
758730554d9SArtem B. Bityutskiy 
759e0c8e42fSArtem B. Bityutskiy 		printk("%02x ", buf[i]);
760e0c8e42fSArtem B. Bityutskiy 
761e0c8e42fSArtem B. Bityutskiy 		i += 1;
762730554d9SArtem B. Bityutskiy 	}
763730554d9SArtem B. Bityutskiy 
764e0c8e42fSArtem B. Bityutskiy 	printk("\n");
765e0c8e42fSArtem B. Bityutskiy }
766e0c8e42fSArtem B. Bityutskiy 
767e0c8e42fSArtem B. Bityutskiy /*
768e0c8e42fSArtem B. Bityutskiy  * Dump a JFFS2 node.
769e0c8e42fSArtem B. Bityutskiy  */
770e0c8e42fSArtem B. Bityutskiy void
771e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs)
772e0c8e42fSArtem B. Bityutskiy {
773e0c8e42fSArtem B. Bityutskiy 	union jffs2_node_union node;
774e0c8e42fSArtem B. Bityutskiy 	int len = sizeof(union jffs2_node_union);
775e0c8e42fSArtem B. Bityutskiy 	size_t retlen;
776e0c8e42fSArtem B. Bityutskiy 	uint32_t crc;
777e0c8e42fSArtem B. Bityutskiy 	int ret;
778e0c8e42fSArtem B. Bityutskiy 
77981e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG_MSG_PREFIX " dump node at offset %#08x.\n", ofs);
780e0c8e42fSArtem B. Bityutskiy 
781e0c8e42fSArtem B. Bityutskiy 	ret = jffs2_flash_read(c, ofs, len, &retlen, (unsigned char *)&node);
782e0c8e42fSArtem B. Bityutskiy 	if (ret || (retlen != len)) {
783e0c8e42fSArtem B. Bityutskiy 		JFFS2_ERROR("read %d bytes failed or short. ret %d, retlen %zd.\n",
784e0c8e42fSArtem B. Bityutskiy 			len, ret, retlen);
785e0c8e42fSArtem B. Bityutskiy 		return;
786e0c8e42fSArtem B. Bityutskiy 	}
787e0c8e42fSArtem B. Bityutskiy 
78881e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "magic:\t%#04x\n", je16_to_cpu(node.u.magic));
78981e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "nodetype:\t%#04x\n", je16_to_cpu(node.u.nodetype));
79081e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "totlen:\t%#08x\n", je32_to_cpu(node.u.totlen));
79181e39cf0SArtem B. Bityutskiy 	printk(JFFS2_DBG "hdr_crc:\t%#08x\n", je32_to_cpu(node.u.hdr_crc));
792e0c8e42fSArtem B. Bityutskiy 
793e0c8e42fSArtem B. Bityutskiy 	crc = crc32(0, &node.u, sizeof(node.u) - 4);
794e0c8e42fSArtem B. Bityutskiy 	if (crc != je32_to_cpu(node.u.hdr_crc)) {
795e0c8e42fSArtem B. Bityutskiy 		JFFS2_ERROR("wrong common header CRC.\n");
796e0c8e42fSArtem B. Bityutskiy 		return;
797e0c8e42fSArtem B. Bityutskiy 	}
798e0c8e42fSArtem B. Bityutskiy 
799e0c8e42fSArtem B. Bityutskiy 	if (je16_to_cpu(node.u.magic) != JFFS2_MAGIC_BITMASK &&
800e0c8e42fSArtem B. Bityutskiy 		je16_to_cpu(node.u.magic) != JFFS2_OLD_MAGIC_BITMASK)
801e0c8e42fSArtem B. Bityutskiy 	{
802e0c8e42fSArtem B. Bityutskiy 		JFFS2_ERROR("wrong node magic: %#04x instead of %#04x.\n",
803e0c8e42fSArtem B. Bityutskiy 			je16_to_cpu(node.u.magic), JFFS2_MAGIC_BITMASK);
804e0c8e42fSArtem B. Bityutskiy 		return;
805e0c8e42fSArtem B. Bityutskiy 	}
806e0c8e42fSArtem B. Bityutskiy 
807e0c8e42fSArtem B. Bityutskiy 	switch(je16_to_cpu(node.u.nodetype)) {
808e0c8e42fSArtem B. Bityutskiy 
809e0c8e42fSArtem B. Bityutskiy 	case JFFS2_NODETYPE_INODE:
810e0c8e42fSArtem B. Bityutskiy 
81181e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "the node is inode node\n");
81281e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.i.ino));
81381e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.i.version));
81481e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "mode:\t%#08x\n", node.i.mode.m);
81581e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "uid:\t%#04x\n", je16_to_cpu(node.i.uid));
81681e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "gid:\t%#04x\n", je16_to_cpu(node.i.gid));
81781e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "isize:\t%#08x\n", je32_to_cpu(node.i.isize));
81881e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "atime:\t%#08x\n", je32_to_cpu(node.i.atime));
81981e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "mtime:\t%#08x\n", je32_to_cpu(node.i.mtime));
82081e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "ctime:\t%#08x\n", je32_to_cpu(node.i.ctime));
82181e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "offset:\t%#08x\n", je32_to_cpu(node.i.offset));
82281e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "csize:\t%#08x\n", je32_to_cpu(node.i.csize));
82381e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "dsize:\t%#08x\n", je32_to_cpu(node.i.dsize));
82481e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "compr:\t%#02x\n", node.i.compr);
82581e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "usercompr:\t%#02x\n", node.i.usercompr);
82681e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "flags:\t%#04x\n", je16_to_cpu(node.i.flags));
82781e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "data_crc:\t%#08x\n", je32_to_cpu(node.i.data_crc));
82881e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.i.node_crc));
82981e39cf0SArtem B. Bityutskiy 
830e0c8e42fSArtem B. Bityutskiy 		crc = crc32(0, &node.i, sizeof(node.i) - 8);
831e0c8e42fSArtem B. Bityutskiy 		if (crc != je32_to_cpu(node.i.node_crc)) {
832e0c8e42fSArtem B. Bityutskiy 			JFFS2_ERROR("wrong node header CRC.\n");
833e0c8e42fSArtem B. Bityutskiy 			return;
834e0c8e42fSArtem B. Bityutskiy 		}
835e0c8e42fSArtem B. Bityutskiy 		break;
836e0c8e42fSArtem B. Bityutskiy 
837e0c8e42fSArtem B. Bityutskiy 	case JFFS2_NODETYPE_DIRENT:
838e0c8e42fSArtem B. Bityutskiy 
83981e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "the node is dirent node\n");
84081e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "pino:\t%#08x\n", je32_to_cpu(node.d.pino));
84181e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.d.version));
84281e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.d.ino));
84381e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "mctime:\t%#08x\n", je32_to_cpu(node.d.mctime));
84481e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "nsize:\t%#02x\n", node.d.nsize);
84581e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "type:\t%#02x\n", node.d.type);
84681e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.d.node_crc));
84781e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "name_crc:\t%#08x\n", je32_to_cpu(node.d.name_crc));
848e0c8e42fSArtem B. Bityutskiy 
849e0c8e42fSArtem B. Bityutskiy 		node.d.name[node.d.nsize] = '\0';
85081e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "name:\t\"%s\"\n", node.d.name);
851e0c8e42fSArtem B. Bityutskiy 
852e0c8e42fSArtem B. Bityutskiy 		crc = crc32(0, &node.d, sizeof(node.d) - 8);
853e0c8e42fSArtem B. Bityutskiy 		if (crc != je32_to_cpu(node.d.node_crc)) {
854e0c8e42fSArtem B. Bityutskiy 			JFFS2_ERROR("wrong node header CRC.\n");
855e0c8e42fSArtem B. Bityutskiy 			return;
856e0c8e42fSArtem B. Bityutskiy 		}
857e0c8e42fSArtem B. Bityutskiy 		break;
858e0c8e42fSArtem B. Bityutskiy 
859e0c8e42fSArtem B. Bityutskiy 	default:
86081e39cf0SArtem B. Bityutskiy 		printk(JFFS2_DBG "node type is unknown\n");
861e0c8e42fSArtem B. Bityutskiy 		break;
862730554d9SArtem B. Bityutskiy 	}
863730554d9SArtem B. Bityutskiy }
864e0c8e42fSArtem B. Bityutskiy #endif /* JFFS2_DBG_DUMPS || JFFS2_DBG_PARANOIA_CHECKS */
865