blob: e198468a8c68e71d4650dd15961e02f9c3b69b72 [file] [log] [blame]
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +01001/*
2 * JFFS2 -- Journalling Flash File System, Version 2.
3 *
David Woodhousec00c3102007-04-25 14:16:47 +01004 * Copyright © 2001-2007 Red Hat, Inc.
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +01005 *
6 * Created by David Woodhouse <dwmw2@infradead.org>
7 *
8 * For licensing information, see the file 'LICENCE' in this directory.
9 *
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010010 */
David Woodhousec00c3102007-04-25 14:16:47 +010011
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010012#include <linux/kernel.h>
Andrew Lunn737b7662005-07-30 16:29:30 +010013#include <linux/types.h>
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010014#include <linux/pagemap.h>
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010015#include <linux/crc32.h>
16#include <linux/jffs2.h>
Artem B. Bityutskiy733802d2005-09-22 12:25:00 +010017#include <linux/mtd/mtd.h>
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010018#include "nodelist.h"
19#include "debug.h"
20
Artem B. Bityutskiy45ca1b52005-08-05 12:43:47 +010021#ifdef JFFS2_DBG_SANITY_CHECKS
22
23void
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);
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +010031 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,
Artem B. Bityutskiy45ca1b52005-08-05 12:43:47 +010033 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");
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +010040 JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + erasing %#08x + bad %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
Artem B. Bityutskiy45ca1b52005-08-05 12:43:47 +010041 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
47void
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
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010058#ifdef JFFS2_DBG_PARANOIA_CHECKS
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010059/*
60 * Check the fragtree.
61 */
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010062void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010063__jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f)
64{
David Woodhouseced22072008-04-22 15:13:40 +010065 mutex_lock(&f->sem);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010066 __jffs2_dbg_fragtree_paranoia_check_nolock(f);
David Woodhouseced22072008-04-22 15:13:40 +010067 mutex_unlock(&f->sem);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010068}
Thomas Gleixner182ec4e2005-11-07 11:16:07 +000069
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010070void
71__jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010072{
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) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010084 JFFS2_ERROR("REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2.\n",
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +010085 ref_offset(fn->raw), fn->frags);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010086 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) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +010096 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));
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010098 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) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100103 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);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100105 bitched = 1;
106 }
107 }
108 }
109
110 if (bitched) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100111 JFFS2_ERROR("fragtree is corrupted.\n");
112 __jffs2_dbg_dump_fragtree_nolock(f);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100113 BUG();
114 }
115}
116
117/*
118 * Check if the flash contains all 0xFF before we start writing.
119 */
120void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100121__jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
122 uint32_t ofs, int len)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100123{
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)) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100134 JFFS2_WARNING("read %d bytes failed or short. ret %d, retlen %zd.\n",
135 len, ret, retlen);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100136 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) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100146 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);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100148 __jffs2_dbg_dump_buffer(buf, len, ofs);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100149 kfree(buf);
150 BUG();
151 }
152
153 kfree(buf);
154}
155
David Woodhouse85a62db2008-04-23 01:17:51 +0100156void __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_complete_list, list) {
250 nr_counted++;
251 erasing += c->sector_size;
252 }
253 list_for_each_entry(jeb, &c->bad_list, list) {
254 nr_counted++;
255 bad += c->sector_size;
256 }
257
258#define check(sz) \
259 if (sz != c->sz##_size) { \
260 printk(KERN_WARNING #sz "_size mismatch counted 0x%x, c->" #sz "_size 0x%x\n", \
261 sz, c->sz##_size); \
262 dump = 1; \
263 }
264 check(free);
265 check(dirty);
266 check(used);
267 check(wasted);
268 check(unchecked);
269 check(bad);
270 check(erasing);
271#undef check
272
273 if (nr_counted != c->nr_blocks) {
274 printk(KERN_WARNING "%s counted only 0x%x blocks of 0x%x. Where are the others?\n",
275 __func__, nr_counted, c->nr_blocks);
276 dump = 1;
277 }
278
279 if (dump) {
280 __jffs2_dbg_dump_block_lists_nolock(c);
281 BUG();
282 }
283}
284
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100285/*
286 * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
287 */
288void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100289__jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c,
290 struct jffs2_eraseblock *jeb)
291{
292 spin_lock(&c->erase_completion_lock);
293 __jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
294 spin_unlock(&c->erase_completion_lock);
295}
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000296
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100297void
298__jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
299 struct jffs2_eraseblock *jeb)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100300{
301 uint32_t my_used_size = 0;
302 uint32_t my_unchecked_size = 0;
303 uint32_t my_dirty_size = 0;
304 struct jffs2_raw_node_ref *ref2 = jeb->first_node;
305
306 while (ref2) {
307 uint32_t totlen = ref_totlen(c, jeb, ref2);
308
Kyungmin Parkabb536e2006-12-22 16:39:30 +0900309 if (ref_offset(ref2) < jeb->offset ||
310 ref_offset(ref2) > jeb->offset + c->sector_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100311 JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100312 ref_offset(ref2), jeb->offset);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100313 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100314
315 }
316 if (ref_flags(ref2) == REF_UNCHECKED)
317 my_unchecked_size += totlen;
318 else if (!ref_obsolete(ref2))
319 my_used_size += totlen;
320 else
321 my_dirty_size += totlen;
322
David Woodhouse99988f72006-05-24 09:04:17 +0100323 if ((!ref_next(ref2)) != (ref2 == jeb->last_node)) {
324 JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next at %#08x (mem %p), last_node is at %#08x (mem %p).\n",
325 ref_offset(ref2), ref2, ref_offset(ref_next(ref2)), ref_next(ref2),
326 ref_offset(jeb->last_node), jeb->last_node);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100327 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100328 }
David Woodhouse99988f72006-05-24 09:04:17 +0100329 ref2 = ref_next(ref2);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100330 }
331
332 if (my_used_size != jeb->used_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100333 JFFS2_ERROR("Calculated used size %#08x != stored used size %#08x.\n",
334 my_used_size, jeb->used_size);
335 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100336 }
337
338 if (my_unchecked_size != jeb->unchecked_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100339 JFFS2_ERROR("Calculated unchecked size %#08x != stored unchecked size %#08x.\n",
340 my_unchecked_size, jeb->unchecked_size);
341 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100342 }
343
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100344#if 0
345 /* This should work when we implement ref->__totlen elemination */
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100346 if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100347 JFFS2_ERROR("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100348 my_dirty_size, jeb->dirty_size + jeb->wasted_size);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100349 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100350 }
351
352 if (jeb->free_size == 0
353 && my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100354 JFFS2_ERROR("The sum of all nodes in block (%#x) != size of block (%#x)\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100355 my_used_size + my_unchecked_size + my_dirty_size,
356 c->sector_size);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100357 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100358 }
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100359#endif
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100360
David Woodhouse85a62db2008-04-23 01:17:51 +0100361 if (!(c->flags & (JFFS2_SB_FLAG_BUILDING|JFFS2_SB_FLAG_SCANNING)))
362 __jffs2_dbg_superblock_counts(c);
363
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100364 return;
365
366error:
367 __jffs2_dbg_dump_node_refs_nolock(c, jeb);
368 __jffs2_dbg_dump_jeb_nolock(jeb);
369 __jffs2_dbg_dump_block_lists_nolock(c);
370 BUG();
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000371
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100372}
373#endif /* JFFS2_DBG_PARANOIA_CHECKS */
374
375#if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100376/*
377 * Dump the node_refs of the 'jeb' JFFS2 eraseblock.
378 */
379void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100380__jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c,
381 struct jffs2_eraseblock *jeb)
382{
383 spin_lock(&c->erase_completion_lock);
384 __jffs2_dbg_dump_node_refs_nolock(c, jeb);
385 spin_unlock(&c->erase_completion_lock);
386}
387
388void
389__jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c,
390 struct jffs2_eraseblock *jeb)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100391{
392 struct jffs2_raw_node_ref *ref;
393 int i = 0;
394
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100395 printk(JFFS2_DBG_MSG_PREFIX " Dump node_refs of the eraseblock %#08x\n", jeb->offset);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100396 if (!jeb->first_node) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100397 printk(JFFS2_DBG_MSG_PREFIX " no nodes in the eraseblock %#08x\n", jeb->offset);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100398 return;
399 }
400
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100401 printk(JFFS2_DBG);
David Woodhouse99988f72006-05-24 09:04:17 +0100402 for (ref = jeb->first_node; ; ref = ref_next(ref)) {
David Woodhouse27e6b8e2008-04-23 01:25:33 +0100403 printk("%#08x", ref_offset(ref));
404#ifdef TEST_TOTLEN
405 printk("(%x)", ref->__totlen);
406#endif
David Woodhouse99988f72006-05-24 09:04:17 +0100407 if (ref_next(ref))
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100408 printk("->");
409 else
410 break;
411 if (++i == 4) {
412 i = 0;
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100413 printk("\n" JFFS2_DBG);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100414 }
415 }
416 printk("\n");
417}
418
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100419/*
420 * Dump an eraseblock's space accounting.
421 */
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100422void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100423__jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100424{
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100425 spin_lock(&c->erase_completion_lock);
426 __jffs2_dbg_dump_jeb_nolock(jeb);
427 spin_unlock(&c->erase_completion_lock);
428}
429
430void
431__jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb)
432{
433 if (!jeb)
434 return;
435
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100436 printk(JFFS2_DBG_MSG_PREFIX " dump space accounting for the eraseblock at %#08x:\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100437 jeb->offset);
438
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100439 printk(JFFS2_DBG "used_size: %#08x\n", jeb->used_size);
440 printk(JFFS2_DBG "dirty_size: %#08x\n", jeb->dirty_size);
441 printk(JFFS2_DBG "wasted_size: %#08x\n", jeb->wasted_size);
442 printk(JFFS2_DBG "unchecked_size: %#08x\n", jeb->unchecked_size);
443 printk(JFFS2_DBG "free_size: %#08x\n", jeb->free_size);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100444}
445
446void
447__jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c)
448{
449 spin_lock(&c->erase_completion_lock);
450 __jffs2_dbg_dump_block_lists_nolock(c);
451 spin_unlock(&c->erase_completion_lock);
452}
453
454void
455__jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c)
456{
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100457 printk(JFFS2_DBG_MSG_PREFIX " dump JFFS2 blocks lists:\n");
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000458
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100459 printk(JFFS2_DBG "flash_size: %#08x\n", c->flash_size);
460 printk(JFFS2_DBG "used_size: %#08x\n", c->used_size);
461 printk(JFFS2_DBG "dirty_size: %#08x\n", c->dirty_size);
462 printk(JFFS2_DBG "wasted_size: %#08x\n", c->wasted_size);
463 printk(JFFS2_DBG "unchecked_size: %#08x\n", c->unchecked_size);
464 printk(JFFS2_DBG "free_size: %#08x\n", c->free_size);
465 printk(JFFS2_DBG "erasing_size: %#08x\n", c->erasing_size);
466 printk(JFFS2_DBG "bad_size: %#08x\n", c->bad_size);
467 printk(JFFS2_DBG "sector_size: %#08x\n", c->sector_size);
468 printk(JFFS2_DBG "jffs2_reserved_blocks size: %#08x\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100469 c->sector_size * c->resv_blocks_write);
470
471 if (c->nextblock)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100472 printk(JFFS2_DBG "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100473 c->nextblock->offset, c->nextblock->used_size,
474 c->nextblock->dirty_size, c->nextblock->wasted_size,
475 c->nextblock->unchecked_size, c->nextblock->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100476 else
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100477 printk(JFFS2_DBG "nextblock: NULL\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100478
479 if (c->gcblock)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100480 printk(JFFS2_DBG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100481 c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size,
482 c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100483 else
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100484 printk(JFFS2_DBG "gcblock: NULL\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100485
486 if (list_empty(&c->clean_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100487 printk(JFFS2_DBG "clean_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100488 } else {
489 struct list_head *this;
490 int numblocks = 0;
491 uint32_t dirty = 0;
492
493 list_for_each(this, &c->clean_list) {
494 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
495 numblocks ++;
496 dirty += jeb->wasted_size;
497 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100498 printk(JFFS2_DBG "clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100499 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
500 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100501 }
502 }
503
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100504 printk (JFFS2_DBG "Contains %d blocks with total wasted size %u, average wasted size: %u\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100505 numblocks, dirty, dirty / numblocks);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100506 }
507
508 if (list_empty(&c->very_dirty_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100509 printk(JFFS2_DBG "very_dirty_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100510 } else {
511 struct list_head *this;
512 int numblocks = 0;
513 uint32_t dirty = 0;
514
515 list_for_each(this, &c->very_dirty_list) {
516 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
517
518 numblocks ++;
519 dirty += jeb->dirty_size;
520 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100521 printk(JFFS2_DBG "very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100522 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
523 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100524 }
525 }
526
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100527 printk (JFFS2_DBG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100528 numblocks, dirty, dirty / numblocks);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100529 }
530
531 if (list_empty(&c->dirty_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100532 printk(JFFS2_DBG "dirty_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100533 } else {
534 struct list_head *this;
535 int numblocks = 0;
536 uint32_t dirty = 0;
537
538 list_for_each(this, &c->dirty_list) {
539 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
540
541 numblocks ++;
542 dirty += jeb->dirty_size;
543 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100544 printk(JFFS2_DBG "dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100545 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
546 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100547 }
548 }
549
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100550 printk (JFFS2_DBG "contains %d blocks with total dirty size %u, average dirty size: %u\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100551 numblocks, dirty, dirty / numblocks);
552 }
553
554 if (list_empty(&c->erasable_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100555 printk(JFFS2_DBG "erasable_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100556 } else {
557 struct list_head *this;
558
559 list_for_each(this, &c->erasable_list) {
560 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
561
562 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100563 printk(JFFS2_DBG "erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100564 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
565 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100566 }
567 }
568 }
569
570 if (list_empty(&c->erasing_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100571 printk(JFFS2_DBG "erasing_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100572 } else {
573 struct list_head *this;
574
575 list_for_each(this, &c->erasing_list) {
576 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
577
578 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100579 printk(JFFS2_DBG "erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100580 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
581 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100582 }
583 }
584 }
585
586 if (list_empty(&c->erase_pending_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100587 printk(JFFS2_DBG "erase_pending_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100588 } else {
589 struct list_head *this;
590
591 list_for_each(this, &c->erase_pending_list) {
592 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
593
594 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100595 printk(JFFS2_DBG "erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100596 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
597 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100598 }
599 }
600 }
601
602 if (list_empty(&c->erasable_pending_wbuf_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100603 printk(JFFS2_DBG "erasable_pending_wbuf_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100604 } else {
605 struct list_head *this;
606
607 list_for_each(this, &c->erasable_pending_wbuf_list) {
608 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
609
610 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100611 printk(JFFS2_DBG "erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100612 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
613 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100614 }
615 }
616 }
617
618 if (list_empty(&c->free_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100619 printk(JFFS2_DBG "free_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100620 } else {
621 struct list_head *this;
622
623 list_for_each(this, &c->free_list) {
624 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
625
626 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100627 printk(JFFS2_DBG "free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100628 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
629 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100630 }
631 }
632 }
633
634 if (list_empty(&c->bad_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100635 printk(JFFS2_DBG "bad_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100636 } else {
637 struct list_head *this;
638
639 list_for_each(this, &c->bad_list) {
640 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
641
642 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100643 printk(JFFS2_DBG "bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100644 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
645 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100646 }
647 }
648 }
649
650 if (list_empty(&c->bad_used_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100651 printk(JFFS2_DBG "bad_used_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100652 } else {
653 struct list_head *this;
654
655 list_for_each(this, &c->bad_used_list) {
656 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
657
658 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100659 printk(JFFS2_DBG "bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100660 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
661 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100662 }
663 }
664 }
665}
666
667void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100668__jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f)
669{
David Woodhouseced22072008-04-22 15:13:40 +0100670 mutex_lock(&f->sem);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100671 jffs2_dbg_dump_fragtree_nolock(f);
David Woodhouseced22072008-04-22 15:13:40 +0100672 mutex_unlock(&f->sem);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100673}
674
675void
676__jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100677{
678 struct jffs2_node_frag *this = frag_first(&f->fragtree);
679 uint32_t lastofs = 0;
680 int buggy = 0;
681
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100682 printk(JFFS2_DBG_MSG_PREFIX " dump fragtree of ino #%u\n", f->inocache->ino);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100683 while(this) {
684 if (this->node)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100685 printk(JFFS2_DBG "frag %#04x-%#04x: %#08x(%d) on flash (*%p), left (%p), right (%p), parent (%p)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100686 this->ofs, this->ofs+this->size, ref_offset(this->node->raw),
687 ref_flags(this->node->raw), this, frag_left(this), frag_right(this),
688 frag_parent(this));
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100689 else
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100690 printk(JFFS2_DBG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100691 this->ofs, this->ofs+this->size, this, frag_left(this),
692 frag_right(this), frag_parent(this));
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100693 if (this->ofs != lastofs)
694 buggy = 1;
695 lastofs = this->ofs + this->size;
696 this = frag_next(this);
697 }
698
699 if (f->metadata)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100700 printk(JFFS2_DBG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100701
702 if (buggy) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100703 JFFS2_ERROR("frag tree got a hole in it.\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100704 BUG();
705 }
706}
707
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100708#define JFFS2_BUFDUMP_BYTES_PER_LINE 32
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100709void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100710__jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100711{
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100712 int skip;
713 int i;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000714
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100715 printk(JFFS2_DBG_MSG_PREFIX " dump from offset %#08x to offset %#08x (%x bytes).\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100716 offs, offs + len, len);
717 i = skip = offs % JFFS2_BUFDUMP_BYTES_PER_LINE;
718 offs = offs & ~(JFFS2_BUFDUMP_BYTES_PER_LINE - 1);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000719
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100720 if (skip != 0)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100721 printk(JFFS2_DBG "%#08x: ", offs);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000722
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100723 while (skip--)
724 printk(" ");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100725
726 while (i < len) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100727 if ((i % JFFS2_BUFDUMP_BYTES_PER_LINE) == 0 && i != len -1) {
728 if (i != 0)
729 printk("\n");
730 offs += JFFS2_BUFDUMP_BYTES_PER_LINE;
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100731 printk(JFFS2_DBG "%0#8x: ", offs);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100732 }
733
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100734 printk("%02x ", buf[i]);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000735
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100736 i += 1;
737 }
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100738
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100739 printk("\n");
740}
741
742/*
743 * Dump a JFFS2 node.
744 */
745void
746__jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs)
747{
748 union jffs2_node_union node;
749 int len = sizeof(union jffs2_node_union);
750 size_t retlen;
751 uint32_t crc;
752 int ret;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000753
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100754 printk(JFFS2_DBG_MSG_PREFIX " dump node at offset %#08x.\n", ofs);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100755
756 ret = jffs2_flash_read(c, ofs, len, &retlen, (unsigned char *)&node);
757 if (ret || (retlen != len)) {
758 JFFS2_ERROR("read %d bytes failed or short. ret %d, retlen %zd.\n",
759 len, ret, retlen);
760 return;
761 }
762
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100763 printk(JFFS2_DBG "magic:\t%#04x\n", je16_to_cpu(node.u.magic));
764 printk(JFFS2_DBG "nodetype:\t%#04x\n", je16_to_cpu(node.u.nodetype));
765 printk(JFFS2_DBG "totlen:\t%#08x\n", je32_to_cpu(node.u.totlen));
766 printk(JFFS2_DBG "hdr_crc:\t%#08x\n", je32_to_cpu(node.u.hdr_crc));
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000767
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100768 crc = crc32(0, &node.u, sizeof(node.u) - 4);
769 if (crc != je32_to_cpu(node.u.hdr_crc)) {
770 JFFS2_ERROR("wrong common header CRC.\n");
771 return;
772 }
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000773
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100774 if (je16_to_cpu(node.u.magic) != JFFS2_MAGIC_BITMASK &&
775 je16_to_cpu(node.u.magic) != JFFS2_OLD_MAGIC_BITMASK)
776 {
777 JFFS2_ERROR("wrong node magic: %#04x instead of %#04x.\n",
778 je16_to_cpu(node.u.magic), JFFS2_MAGIC_BITMASK);
779 return;
780 }
781
782 switch(je16_to_cpu(node.u.nodetype)) {
783
784 case JFFS2_NODETYPE_INODE:
785
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100786 printk(JFFS2_DBG "the node is inode node\n");
787 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.i.ino));
788 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.i.version));
789 printk(JFFS2_DBG "mode:\t%#08x\n", node.i.mode.m);
790 printk(JFFS2_DBG "uid:\t%#04x\n", je16_to_cpu(node.i.uid));
791 printk(JFFS2_DBG "gid:\t%#04x\n", je16_to_cpu(node.i.gid));
792 printk(JFFS2_DBG "isize:\t%#08x\n", je32_to_cpu(node.i.isize));
793 printk(JFFS2_DBG "atime:\t%#08x\n", je32_to_cpu(node.i.atime));
794 printk(JFFS2_DBG "mtime:\t%#08x\n", je32_to_cpu(node.i.mtime));
795 printk(JFFS2_DBG "ctime:\t%#08x\n", je32_to_cpu(node.i.ctime));
796 printk(JFFS2_DBG "offset:\t%#08x\n", je32_to_cpu(node.i.offset));
797 printk(JFFS2_DBG "csize:\t%#08x\n", je32_to_cpu(node.i.csize));
798 printk(JFFS2_DBG "dsize:\t%#08x\n", je32_to_cpu(node.i.dsize));
799 printk(JFFS2_DBG "compr:\t%#02x\n", node.i.compr);
800 printk(JFFS2_DBG "usercompr:\t%#02x\n", node.i.usercompr);
801 printk(JFFS2_DBG "flags:\t%#04x\n", je16_to_cpu(node.i.flags));
802 printk(JFFS2_DBG "data_crc:\t%#08x\n", je32_to_cpu(node.i.data_crc));
803 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.i.node_crc));
804
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000805 crc = crc32(0, &node.i, sizeof(node.i) - 8);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100806 if (crc != je32_to_cpu(node.i.node_crc)) {
807 JFFS2_ERROR("wrong node header CRC.\n");
808 return;
809 }
810 break;
811
812 case JFFS2_NODETYPE_DIRENT:
813
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100814 printk(JFFS2_DBG "the node is dirent node\n");
815 printk(JFFS2_DBG "pino:\t%#08x\n", je32_to_cpu(node.d.pino));
816 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.d.version));
817 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.d.ino));
818 printk(JFFS2_DBG "mctime:\t%#08x\n", je32_to_cpu(node.d.mctime));
819 printk(JFFS2_DBG "nsize:\t%#02x\n", node.d.nsize);
820 printk(JFFS2_DBG "type:\t%#02x\n", node.d.type);
821 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.d.node_crc));
822 printk(JFFS2_DBG "name_crc:\t%#08x\n", je32_to_cpu(node.d.name_crc));
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000823
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100824 node.d.name[node.d.nsize] = '\0';
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100825 printk(JFFS2_DBG "name:\t\"%s\"\n", node.d.name);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100826
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000827 crc = crc32(0, &node.d, sizeof(node.d) - 8);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100828 if (crc != je32_to_cpu(node.d.node_crc)) {
829 JFFS2_ERROR("wrong node header CRC.\n");
830 return;
831 }
832 break;
833
834 default:
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100835 printk(JFFS2_DBG "node type is unknown\n");
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100836 break;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100837 }
838}
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100839#endif /* JFFS2_DBG_DUMPS || JFFS2_DBG_PARANOIA_CHECKS */