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