blob: ec3538413926f677feb3d763df9a7ebaa5d7a07d [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>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090018#include <linux/slab.h>
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010019#include "nodelist.h"
20#include "debug.h"
21
Artem B. Bityutskiy45ca1b52005-08-05 12:43:47 +010022#ifdef JFFS2_DBG_SANITY_CHECKS
23
24void
25__jffs2_dbg_acct_sanity_check_nolock(struct jffs2_sb_info *c,
26 struct jffs2_eraseblock *jeb)
27{
28 if (unlikely(jeb && jeb->used_size + jeb->dirty_size +
29 jeb->free_size + jeb->wasted_size +
30 jeb->unchecked_size != c->sector_size)) {
31 JFFS2_ERROR("eeep, space accounting for block at 0x%08x is screwed.\n", jeb->offset);
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +010032 JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
33 jeb->free_size, jeb->dirty_size, jeb->used_size,
Artem B. Bityutskiy45ca1b52005-08-05 12:43:47 +010034 jeb->wasted_size, jeb->unchecked_size, c->sector_size);
35 BUG();
36 }
37
38 if (unlikely(c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size
39 + c->wasted_size + c->unchecked_size != c->flash_size)) {
40 JFFS2_ERROR("eeep, space accounting superblock info is screwed.\n");
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +010041 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 +010042 c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size,
43 c->wasted_size, c->unchecked_size, c->flash_size);
44 BUG();
45 }
46}
47
48void
49__jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c,
50 struct jffs2_eraseblock *jeb)
51{
52 spin_lock(&c->erase_completion_lock);
53 jffs2_dbg_acct_sanity_check_nolock(c, jeb);
54 spin_unlock(&c->erase_completion_lock);
55}
56
57#endif /* JFFS2_DBG_SANITY_CHECKS */
58
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010059#ifdef JFFS2_DBG_PARANOIA_CHECKS
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010060/*
61 * Check the fragtree.
62 */
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010063void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010064__jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f)
65{
David Woodhouseced22072008-04-22 15:13:40 +010066 mutex_lock(&f->sem);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010067 __jffs2_dbg_fragtree_paranoia_check_nolock(f);
David Woodhouseced22072008-04-22 15:13:40 +010068 mutex_unlock(&f->sem);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010069}
Thomas Gleixner182ec4e2005-11-07 11:16:07 +000070
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010071void
72__jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010073{
74 struct jffs2_node_frag *frag;
75 int bitched = 0;
76
77 for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
78 struct jffs2_full_dnode *fn = frag->node;
79
80 if (!fn || !fn->raw)
81 continue;
82
83 if (ref_flags(fn->raw) == REF_PRISTINE) {
84 if (fn->frags > 1) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010085 JFFS2_ERROR("REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2.\n",
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +010086 ref_offset(fn->raw), fn->frags);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010087 bitched = 1;
88 }
89
90 /* A hole node which isn't multi-page should be garbage-collected
91 and merged anyway, so we just check for the frag size here,
92 rather than mucking around with actually reading the node
93 and checking the compression type, which is the real way
94 to tell a hole node. */
95 if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag)
96 && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +010097 JFFS2_ERROR("REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2.\n",
98 ref_offset(fn->raw));
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010099 bitched = 1;
100 }
101
102 if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag)
103 && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100104 JFFS2_ERROR("REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2.\n",
105 ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100106 bitched = 1;
107 }
108 }
109 }
110
111 if (bitched) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100112 JFFS2_ERROR("fragtree is corrupted.\n");
113 __jffs2_dbg_dump_fragtree_nolock(f);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100114 BUG();
115 }
116}
117
118/*
119 * Check if the flash contains all 0xFF before we start writing.
120 */
121void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100122__jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
123 uint32_t ofs, int len)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100124{
125 size_t retlen;
126 int ret, i;
127 unsigned char *buf;
128
129 buf = kmalloc(len, GFP_KERNEL);
130 if (!buf)
131 return;
132
133 ret = jffs2_flash_read(c, ofs, len, &retlen, buf);
134 if (ret || (retlen != len)) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100135 JFFS2_WARNING("read %d bytes failed or short. ret %d, retlen %zd.\n",
136 len, ret, retlen);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100137 kfree(buf);
138 return;
139 }
140
141 ret = 0;
142 for (i = 0; i < len; i++)
143 if (buf[i] != 0xff)
144 ret = 1;
145
146 if (ret) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100147 JFFS2_ERROR("argh, about to write node to %#08x on flash, but there are data already there. The first corrupted byte is at %#08x offset.\n",
148 ofs, ofs + i);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100149 __jffs2_dbg_dump_buffer(buf, len, ofs);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100150 kfree(buf);
151 BUG();
152 }
153
154 kfree(buf);
155}
156
David Woodhouse85a62db2008-04-23 01:17:51 +0100157void __jffs2_dbg_superblock_counts(struct jffs2_sb_info *c)
158{
159 struct jffs2_eraseblock *jeb;
160 uint32_t free = 0, dirty = 0, used = 0, wasted = 0,
161 erasing = 0, bad = 0, unchecked = 0;
162 int nr_counted = 0;
163 int dump = 0;
164
165 if (c->gcblock) {
166 nr_counted++;
167 free += c->gcblock->free_size;
168 dirty += c->gcblock->dirty_size;
169 used += c->gcblock->used_size;
170 wasted += c->gcblock->wasted_size;
171 unchecked += c->gcblock->unchecked_size;
172 }
173 if (c->nextblock) {
174 nr_counted++;
175 free += c->nextblock->free_size;
176 dirty += c->nextblock->dirty_size;
177 used += c->nextblock->used_size;
178 wasted += c->nextblock->wasted_size;
179 unchecked += c->nextblock->unchecked_size;
180 }
181 list_for_each_entry(jeb, &c->clean_list, list) {
182 nr_counted++;
183 free += jeb->free_size;
184 dirty += jeb->dirty_size;
185 used += jeb->used_size;
186 wasted += jeb->wasted_size;
187 unchecked += jeb->unchecked_size;
188 }
189 list_for_each_entry(jeb, &c->very_dirty_list, list) {
190 nr_counted++;
191 free += jeb->free_size;
192 dirty += jeb->dirty_size;
193 used += jeb->used_size;
194 wasted += jeb->wasted_size;
195 unchecked += jeb->unchecked_size;
196 }
197 list_for_each_entry(jeb, &c->dirty_list, list) {
198 nr_counted++;
199 free += jeb->free_size;
200 dirty += jeb->dirty_size;
201 used += jeb->used_size;
202 wasted += jeb->wasted_size;
203 unchecked += jeb->unchecked_size;
204 }
205 list_for_each_entry(jeb, &c->erasable_list, list) {
206 nr_counted++;
207 free += jeb->free_size;
208 dirty += jeb->dirty_size;
209 used += jeb->used_size;
210 wasted += jeb->wasted_size;
211 unchecked += jeb->unchecked_size;
212 }
213 list_for_each_entry(jeb, &c->erasable_pending_wbuf_list, list) {
214 nr_counted++;
215 free += jeb->free_size;
216 dirty += jeb->dirty_size;
217 used += jeb->used_size;
218 wasted += jeb->wasted_size;
219 unchecked += jeb->unchecked_size;
220 }
221 list_for_each_entry(jeb, &c->erase_pending_list, list) {
222 nr_counted++;
223 free += jeb->free_size;
224 dirty += jeb->dirty_size;
225 used += jeb->used_size;
226 wasted += jeb->wasted_size;
227 unchecked += jeb->unchecked_size;
228 }
229 list_for_each_entry(jeb, &c->free_list, list) {
230 nr_counted++;
231 free += jeb->free_size;
232 dirty += jeb->dirty_size;
233 used += jeb->used_size;
234 wasted += jeb->wasted_size;
235 unchecked += jeb->unchecked_size;
236 }
237 list_for_each_entry(jeb, &c->bad_used_list, list) {
238 nr_counted++;
239 free += jeb->free_size;
240 dirty += jeb->dirty_size;
241 used += jeb->used_size;
242 wasted += jeb->wasted_size;
243 unchecked += jeb->unchecked_size;
244 }
245
246 list_for_each_entry(jeb, &c->erasing_list, list) {
247 nr_counted++;
248 erasing += c->sector_size;
249 }
David Woodhousee2bc3222008-04-23 14:15:24 +0100250 list_for_each_entry(jeb, &c->erase_checking_list, list) {
251 nr_counted++;
252 erasing += c->sector_size;
253 }
David Woodhouse85a62db2008-04-23 01:17:51 +0100254 list_for_each_entry(jeb, &c->erase_complete_list, list) {
255 nr_counted++;
256 erasing += c->sector_size;
257 }
258 list_for_each_entry(jeb, &c->bad_list, list) {
259 nr_counted++;
260 bad += c->sector_size;
261 }
262
263#define check(sz) \
264 if (sz != c->sz##_size) { \
265 printk(KERN_WARNING #sz "_size mismatch counted 0x%x, c->" #sz "_size 0x%x\n", \
266 sz, c->sz##_size); \
267 dump = 1; \
268 }
269 check(free);
270 check(dirty);
271 check(used);
272 check(wasted);
273 check(unchecked);
274 check(bad);
275 check(erasing);
276#undef check
277
278 if (nr_counted != c->nr_blocks) {
279 printk(KERN_WARNING "%s counted only 0x%x blocks of 0x%x. Where are the others?\n",
280 __func__, nr_counted, c->nr_blocks);
281 dump = 1;
282 }
283
284 if (dump) {
285 __jffs2_dbg_dump_block_lists_nolock(c);
286 BUG();
287 }
288}
289
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100290/*
291 * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
292 */
293void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100294__jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c,
295 struct jffs2_eraseblock *jeb)
296{
297 spin_lock(&c->erase_completion_lock);
298 __jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
299 spin_unlock(&c->erase_completion_lock);
300}
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000301
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100302void
303__jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
304 struct jffs2_eraseblock *jeb)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100305{
306 uint32_t my_used_size = 0;
307 uint32_t my_unchecked_size = 0;
308 uint32_t my_dirty_size = 0;
309 struct jffs2_raw_node_ref *ref2 = jeb->first_node;
310
311 while (ref2) {
312 uint32_t totlen = ref_totlen(c, jeb, ref2);
313
Kyungmin Parkabb536e2006-12-22 16:39:30 +0900314 if (ref_offset(ref2) < jeb->offset ||
315 ref_offset(ref2) > jeb->offset + c->sector_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100316 JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100317 ref_offset(ref2), jeb->offset);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100318 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100319
320 }
321 if (ref_flags(ref2) == REF_UNCHECKED)
322 my_unchecked_size += totlen;
323 else if (!ref_obsolete(ref2))
324 my_used_size += totlen;
325 else
326 my_dirty_size += totlen;
327
David Woodhouse99988f72006-05-24 09:04:17 +0100328 if ((!ref_next(ref2)) != (ref2 == jeb->last_node)) {
329 JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next at %#08x (mem %p), last_node is at %#08x (mem %p).\n",
330 ref_offset(ref2), ref2, ref_offset(ref_next(ref2)), ref_next(ref2),
331 ref_offset(jeb->last_node), jeb->last_node);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100332 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100333 }
David Woodhouse99988f72006-05-24 09:04:17 +0100334 ref2 = ref_next(ref2);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100335 }
336
337 if (my_used_size != jeb->used_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100338 JFFS2_ERROR("Calculated used size %#08x != stored used size %#08x.\n",
339 my_used_size, jeb->used_size);
340 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100341 }
342
343 if (my_unchecked_size != jeb->unchecked_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100344 JFFS2_ERROR("Calculated unchecked size %#08x != stored unchecked size %#08x.\n",
345 my_unchecked_size, jeb->unchecked_size);
346 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100347 }
348
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100349#if 0
350 /* This should work when we implement ref->__totlen elemination */
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100351 if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100352 JFFS2_ERROR("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100353 my_dirty_size, jeb->dirty_size + jeb->wasted_size);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100354 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100355 }
356
357 if (jeb->free_size == 0
358 && my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100359 JFFS2_ERROR("The sum of all nodes in block (%#x) != size of block (%#x)\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100360 my_used_size + my_unchecked_size + my_dirty_size,
361 c->sector_size);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100362 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100363 }
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100364#endif
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100365
David Woodhouse85a62db2008-04-23 01:17:51 +0100366 if (!(c->flags & (JFFS2_SB_FLAG_BUILDING|JFFS2_SB_FLAG_SCANNING)))
367 __jffs2_dbg_superblock_counts(c);
368
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100369 return;
370
371error:
372 __jffs2_dbg_dump_node_refs_nolock(c, jeb);
373 __jffs2_dbg_dump_jeb_nolock(jeb);
374 __jffs2_dbg_dump_block_lists_nolock(c);
375 BUG();
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000376
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100377}
378#endif /* JFFS2_DBG_PARANOIA_CHECKS */
379
380#if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100381/*
382 * Dump the node_refs of the 'jeb' JFFS2 eraseblock.
383 */
384void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100385__jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c,
386 struct jffs2_eraseblock *jeb)
387{
388 spin_lock(&c->erase_completion_lock);
389 __jffs2_dbg_dump_node_refs_nolock(c, jeb);
390 spin_unlock(&c->erase_completion_lock);
391}
392
393void
394__jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c,
395 struct jffs2_eraseblock *jeb)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100396{
397 struct jffs2_raw_node_ref *ref;
398 int i = 0;
399
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100400 printk(JFFS2_DBG_MSG_PREFIX " Dump node_refs of the eraseblock %#08x\n", jeb->offset);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100401 if (!jeb->first_node) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100402 printk(JFFS2_DBG_MSG_PREFIX " no nodes in the eraseblock %#08x\n", jeb->offset);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100403 return;
404 }
405
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100406 printk(JFFS2_DBG);
David Woodhouse99988f72006-05-24 09:04:17 +0100407 for (ref = jeb->first_node; ; ref = ref_next(ref)) {
David Woodhouse27e6b8e2008-04-23 01:25:33 +0100408 printk("%#08x", ref_offset(ref));
409#ifdef TEST_TOTLEN
410 printk("(%x)", ref->__totlen);
411#endif
David Woodhouse99988f72006-05-24 09:04:17 +0100412 if (ref_next(ref))
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100413 printk("->");
414 else
415 break;
416 if (++i == 4) {
417 i = 0;
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100418 printk("\n" JFFS2_DBG);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100419 }
420 }
421 printk("\n");
422}
423
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100424/*
425 * Dump an eraseblock's space accounting.
426 */
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100427void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100428__jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100429{
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100430 spin_lock(&c->erase_completion_lock);
431 __jffs2_dbg_dump_jeb_nolock(jeb);
432 spin_unlock(&c->erase_completion_lock);
433}
434
435void
436__jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb)
437{
438 if (!jeb)
439 return;
440
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100441 printk(JFFS2_DBG_MSG_PREFIX " dump space accounting for the eraseblock at %#08x:\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100442 jeb->offset);
443
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100444 printk(JFFS2_DBG "used_size: %#08x\n", jeb->used_size);
445 printk(JFFS2_DBG "dirty_size: %#08x\n", jeb->dirty_size);
446 printk(JFFS2_DBG "wasted_size: %#08x\n", jeb->wasted_size);
447 printk(JFFS2_DBG "unchecked_size: %#08x\n", jeb->unchecked_size);
448 printk(JFFS2_DBG "free_size: %#08x\n", jeb->free_size);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100449}
450
451void
452__jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c)
453{
454 spin_lock(&c->erase_completion_lock);
455 __jffs2_dbg_dump_block_lists_nolock(c);
456 spin_unlock(&c->erase_completion_lock);
457}
458
459void
460__jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c)
461{
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100462 printk(JFFS2_DBG_MSG_PREFIX " dump JFFS2 blocks lists:\n");
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000463
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100464 printk(JFFS2_DBG "flash_size: %#08x\n", c->flash_size);
465 printk(JFFS2_DBG "used_size: %#08x\n", c->used_size);
466 printk(JFFS2_DBG "dirty_size: %#08x\n", c->dirty_size);
467 printk(JFFS2_DBG "wasted_size: %#08x\n", c->wasted_size);
468 printk(JFFS2_DBG "unchecked_size: %#08x\n", c->unchecked_size);
469 printk(JFFS2_DBG "free_size: %#08x\n", c->free_size);
470 printk(JFFS2_DBG "erasing_size: %#08x\n", c->erasing_size);
471 printk(JFFS2_DBG "bad_size: %#08x\n", c->bad_size);
472 printk(JFFS2_DBG "sector_size: %#08x\n", c->sector_size);
473 printk(JFFS2_DBG "jffs2_reserved_blocks size: %#08x\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100474 c->sector_size * c->resv_blocks_write);
475
476 if (c->nextblock)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100477 printk(JFFS2_DBG "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100478 c->nextblock->offset, c->nextblock->used_size,
479 c->nextblock->dirty_size, c->nextblock->wasted_size,
480 c->nextblock->unchecked_size, c->nextblock->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100481 else
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100482 printk(JFFS2_DBG "nextblock: NULL\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100483
484 if (c->gcblock)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100485 printk(JFFS2_DBG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100486 c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size,
487 c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100488 else
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100489 printk(JFFS2_DBG "gcblock: NULL\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100490
491 if (list_empty(&c->clean_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100492 printk(JFFS2_DBG "clean_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100493 } else {
494 struct list_head *this;
495 int numblocks = 0;
496 uint32_t dirty = 0;
497
498 list_for_each(this, &c->clean_list) {
499 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
500 numblocks ++;
501 dirty += jeb->wasted_size;
502 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100503 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 +0100504 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
505 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100506 }
507 }
508
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100509 printk (JFFS2_DBG "Contains %d blocks with total wasted size %u, average wasted size: %u\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100510 numblocks, dirty, dirty / numblocks);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100511 }
512
513 if (list_empty(&c->very_dirty_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100514 printk(JFFS2_DBG "very_dirty_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100515 } else {
516 struct list_head *this;
517 int numblocks = 0;
518 uint32_t dirty = 0;
519
520 list_for_each(this, &c->very_dirty_list) {
521 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
522
523 numblocks ++;
524 dirty += jeb->dirty_size;
525 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100526 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 +0100527 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
528 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100529 }
530 }
531
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100532 printk (JFFS2_DBG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100533 numblocks, dirty, dirty / numblocks);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100534 }
535
536 if (list_empty(&c->dirty_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100537 printk(JFFS2_DBG "dirty_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100538 } else {
539 struct list_head *this;
540 int numblocks = 0;
541 uint32_t dirty = 0;
542
543 list_for_each(this, &c->dirty_list) {
544 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
545
546 numblocks ++;
547 dirty += jeb->dirty_size;
548 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100549 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 +0100550 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
551 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100552 }
553 }
554
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100555 printk (JFFS2_DBG "contains %d blocks with total dirty size %u, average dirty size: %u\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100556 numblocks, dirty, dirty / numblocks);
557 }
558
559 if (list_empty(&c->erasable_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100560 printk(JFFS2_DBG "erasable_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100561 } else {
562 struct list_head *this;
563
564 list_for_each(this, &c->erasable_list) {
565 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
566
567 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100568 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 +0100569 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
570 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100571 }
572 }
573 }
574
575 if (list_empty(&c->erasing_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100576 printk(JFFS2_DBG "erasing_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100577 } else {
578 struct list_head *this;
579
580 list_for_each(this, &c->erasing_list) {
581 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
582
583 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100584 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 +0100585 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
586 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100587 }
588 }
589 }
David Woodhousee2bc3222008-04-23 14:15:24 +0100590 if (list_empty(&c->erase_checking_list)) {
591 printk(JFFS2_DBG "erase_checking_list: empty\n");
592 } else {
593 struct list_head *this;
594
595 list_for_each(this, &c->erase_checking_list) {
596 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
597
598 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
599 printk(JFFS2_DBG "erase_checking_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
600 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
601 jeb->unchecked_size, jeb->free_size);
602 }
603 }
604 }
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100605
606 if (list_empty(&c->erase_pending_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100607 printk(JFFS2_DBG "erase_pending_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100608 } else {
609 struct list_head *this;
610
611 list_for_each(this, &c->erase_pending_list) {
612 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
613
614 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100615 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 +0100616 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
617 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100618 }
619 }
620 }
621
622 if (list_empty(&c->erasable_pending_wbuf_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100623 printk(JFFS2_DBG "erasable_pending_wbuf_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100624 } else {
625 struct list_head *this;
626
627 list_for_each(this, &c->erasable_pending_wbuf_list) {
628 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
629
630 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100631 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 +0100632 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
633 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100634 }
635 }
636 }
637
638 if (list_empty(&c->free_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100639 printk(JFFS2_DBG "free_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100640 } else {
641 struct list_head *this;
642
643 list_for_each(this, &c->free_list) {
644 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
645
646 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100647 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 +0100648 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
649 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100650 }
651 }
652 }
653
654 if (list_empty(&c->bad_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100655 printk(JFFS2_DBG "bad_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100656 } else {
657 struct list_head *this;
658
659 list_for_each(this, &c->bad_list) {
660 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
661
662 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100663 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 +0100664 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
665 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100666 }
667 }
668 }
669
670 if (list_empty(&c->bad_used_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100671 printk(JFFS2_DBG "bad_used_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100672 } else {
673 struct list_head *this;
674
675 list_for_each(this, &c->bad_used_list) {
676 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
677
678 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100679 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 +0100680 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
681 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100682 }
683 }
684 }
685}
686
687void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100688__jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f)
689{
David Woodhouseced22072008-04-22 15:13:40 +0100690 mutex_lock(&f->sem);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100691 jffs2_dbg_dump_fragtree_nolock(f);
David Woodhouseced22072008-04-22 15:13:40 +0100692 mutex_unlock(&f->sem);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100693}
694
695void
696__jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100697{
698 struct jffs2_node_frag *this = frag_first(&f->fragtree);
699 uint32_t lastofs = 0;
700 int buggy = 0;
701
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100702 printk(JFFS2_DBG_MSG_PREFIX " dump fragtree of ino #%u\n", f->inocache->ino);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100703 while(this) {
704 if (this->node)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100705 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 +0100706 this->ofs, this->ofs+this->size, ref_offset(this->node->raw),
707 ref_flags(this->node->raw), this, frag_left(this), frag_right(this),
708 frag_parent(this));
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100709 else
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100710 printk(JFFS2_DBG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100711 this->ofs, this->ofs+this->size, this, frag_left(this),
712 frag_right(this), frag_parent(this));
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100713 if (this->ofs != lastofs)
714 buggy = 1;
715 lastofs = this->ofs + this->size;
716 this = frag_next(this);
717 }
718
719 if (f->metadata)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100720 printk(JFFS2_DBG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100721
722 if (buggy) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100723 JFFS2_ERROR("frag tree got a hole in it.\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100724 BUG();
725 }
726}
727
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100728#define JFFS2_BUFDUMP_BYTES_PER_LINE 32
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100729void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100730__jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100731{
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100732 int skip;
733 int i;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000734
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100735 printk(JFFS2_DBG_MSG_PREFIX " dump from offset %#08x to offset %#08x (%x bytes).\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100736 offs, offs + len, len);
737 i = skip = offs % JFFS2_BUFDUMP_BYTES_PER_LINE;
738 offs = offs & ~(JFFS2_BUFDUMP_BYTES_PER_LINE - 1);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000739
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100740 if (skip != 0)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100741 printk(JFFS2_DBG "%#08x: ", offs);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000742
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100743 while (skip--)
744 printk(" ");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100745
746 while (i < len) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100747 if ((i % JFFS2_BUFDUMP_BYTES_PER_LINE) == 0 && i != len -1) {
748 if (i != 0)
749 printk("\n");
750 offs += JFFS2_BUFDUMP_BYTES_PER_LINE;
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100751 printk(JFFS2_DBG "%0#8x: ", offs);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100752 }
753
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100754 printk("%02x ", buf[i]);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000755
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100756 i += 1;
757 }
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100758
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100759 printk("\n");
760}
761
762/*
763 * Dump a JFFS2 node.
764 */
765void
766__jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs)
767{
768 union jffs2_node_union node;
769 int len = sizeof(union jffs2_node_union);
770 size_t retlen;
771 uint32_t crc;
772 int ret;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000773
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100774 printk(JFFS2_DBG_MSG_PREFIX " dump node at offset %#08x.\n", ofs);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100775
776 ret = jffs2_flash_read(c, ofs, len, &retlen, (unsigned char *)&node);
777 if (ret || (retlen != len)) {
778 JFFS2_ERROR("read %d bytes failed or short. ret %d, retlen %zd.\n",
779 len, ret, retlen);
780 return;
781 }
782
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100783 printk(JFFS2_DBG "magic:\t%#04x\n", je16_to_cpu(node.u.magic));
784 printk(JFFS2_DBG "nodetype:\t%#04x\n", je16_to_cpu(node.u.nodetype));
785 printk(JFFS2_DBG "totlen:\t%#08x\n", je32_to_cpu(node.u.totlen));
786 printk(JFFS2_DBG "hdr_crc:\t%#08x\n", je32_to_cpu(node.u.hdr_crc));
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000787
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100788 crc = crc32(0, &node.u, sizeof(node.u) - 4);
789 if (crc != je32_to_cpu(node.u.hdr_crc)) {
790 JFFS2_ERROR("wrong common header CRC.\n");
791 return;
792 }
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000793
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100794 if (je16_to_cpu(node.u.magic) != JFFS2_MAGIC_BITMASK &&
795 je16_to_cpu(node.u.magic) != JFFS2_OLD_MAGIC_BITMASK)
796 {
797 JFFS2_ERROR("wrong node magic: %#04x instead of %#04x.\n",
798 je16_to_cpu(node.u.magic), JFFS2_MAGIC_BITMASK);
799 return;
800 }
801
802 switch(je16_to_cpu(node.u.nodetype)) {
803
804 case JFFS2_NODETYPE_INODE:
805
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100806 printk(JFFS2_DBG "the node is inode node\n");
807 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.i.ino));
808 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.i.version));
809 printk(JFFS2_DBG "mode:\t%#08x\n", node.i.mode.m);
810 printk(JFFS2_DBG "uid:\t%#04x\n", je16_to_cpu(node.i.uid));
811 printk(JFFS2_DBG "gid:\t%#04x\n", je16_to_cpu(node.i.gid));
812 printk(JFFS2_DBG "isize:\t%#08x\n", je32_to_cpu(node.i.isize));
813 printk(JFFS2_DBG "atime:\t%#08x\n", je32_to_cpu(node.i.atime));
814 printk(JFFS2_DBG "mtime:\t%#08x\n", je32_to_cpu(node.i.mtime));
815 printk(JFFS2_DBG "ctime:\t%#08x\n", je32_to_cpu(node.i.ctime));
816 printk(JFFS2_DBG "offset:\t%#08x\n", je32_to_cpu(node.i.offset));
817 printk(JFFS2_DBG "csize:\t%#08x\n", je32_to_cpu(node.i.csize));
818 printk(JFFS2_DBG "dsize:\t%#08x\n", je32_to_cpu(node.i.dsize));
819 printk(JFFS2_DBG "compr:\t%#02x\n", node.i.compr);
820 printk(JFFS2_DBG "usercompr:\t%#02x\n", node.i.usercompr);
821 printk(JFFS2_DBG "flags:\t%#04x\n", je16_to_cpu(node.i.flags));
822 printk(JFFS2_DBG "data_crc:\t%#08x\n", je32_to_cpu(node.i.data_crc));
823 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.i.node_crc));
824
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000825 crc = crc32(0, &node.i, sizeof(node.i) - 8);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100826 if (crc != je32_to_cpu(node.i.node_crc)) {
827 JFFS2_ERROR("wrong node header CRC.\n");
828 return;
829 }
830 break;
831
832 case JFFS2_NODETYPE_DIRENT:
833
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100834 printk(JFFS2_DBG "the node is dirent node\n");
835 printk(JFFS2_DBG "pino:\t%#08x\n", je32_to_cpu(node.d.pino));
836 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.d.version));
837 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.d.ino));
838 printk(JFFS2_DBG "mctime:\t%#08x\n", je32_to_cpu(node.d.mctime));
839 printk(JFFS2_DBG "nsize:\t%#02x\n", node.d.nsize);
840 printk(JFFS2_DBG "type:\t%#02x\n", node.d.type);
841 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.d.node_crc));
842 printk(JFFS2_DBG "name_crc:\t%#08x\n", je32_to_cpu(node.d.name_crc));
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000843
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100844 node.d.name[node.d.nsize] = '\0';
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100845 printk(JFFS2_DBG "name:\t\"%s\"\n", node.d.name);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100846
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000847 crc = crc32(0, &node.d, sizeof(node.d) - 8);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100848 if (crc != je32_to_cpu(node.d.node_crc)) {
849 JFFS2_ERROR("wrong node header CRC.\n");
850 return;
851 }
852 break;
853
854 default:
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100855 printk(JFFS2_DBG "node type is unknown\n");
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100856 break;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100857 }
858}
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100859#endif /* JFFS2_DBG_DUMPS || JFFS2_DBG_PARANOIA_CHECKS */