blob: 5544d31c066be22fb25cc857df3691de8e420ea6 [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 }
David Woodhousee2bc3222008-04-23 14:15:24 +0100249 list_for_each_entry(jeb, &c->erase_checking_list, list) {
250 nr_counted++;
251 erasing += c->sector_size;
252 }
David Woodhouse85a62db2008-04-23 01:17:51 +0100253 list_for_each_entry(jeb, &c->erase_complete_list, list) {
254 nr_counted++;
255 erasing += c->sector_size;
256 }
257 list_for_each_entry(jeb, &c->bad_list, list) {
258 nr_counted++;
259 bad += c->sector_size;
260 }
261
262#define check(sz) \
263 if (sz != c->sz##_size) { \
264 printk(KERN_WARNING #sz "_size mismatch counted 0x%x, c->" #sz "_size 0x%x\n", \
265 sz, c->sz##_size); \
266 dump = 1; \
267 }
268 check(free);
269 check(dirty);
270 check(used);
271 check(wasted);
272 check(unchecked);
273 check(bad);
274 check(erasing);
275#undef check
276
277 if (nr_counted != c->nr_blocks) {
278 printk(KERN_WARNING "%s counted only 0x%x blocks of 0x%x. Where are the others?\n",
279 __func__, nr_counted, c->nr_blocks);
280 dump = 1;
281 }
282
283 if (dump) {
284 __jffs2_dbg_dump_block_lists_nolock(c);
285 BUG();
286 }
287}
288
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100289/*
290 * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
291 */
292void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100293__jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c,
294 struct jffs2_eraseblock *jeb)
295{
296 spin_lock(&c->erase_completion_lock);
297 __jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
298 spin_unlock(&c->erase_completion_lock);
299}
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000300
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100301void
302__jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
303 struct jffs2_eraseblock *jeb)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100304{
305 uint32_t my_used_size = 0;
306 uint32_t my_unchecked_size = 0;
307 uint32_t my_dirty_size = 0;
308 struct jffs2_raw_node_ref *ref2 = jeb->first_node;
309
310 while (ref2) {
311 uint32_t totlen = ref_totlen(c, jeb, ref2);
312
Kyungmin Parkabb536e2006-12-22 16:39:30 +0900313 if (ref_offset(ref2) < jeb->offset ||
314 ref_offset(ref2) > jeb->offset + c->sector_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100315 JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100316 ref_offset(ref2), jeb->offset);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100317 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100318
319 }
320 if (ref_flags(ref2) == REF_UNCHECKED)
321 my_unchecked_size += totlen;
322 else if (!ref_obsolete(ref2))
323 my_used_size += totlen;
324 else
325 my_dirty_size += totlen;
326
David Woodhouse99988f72006-05-24 09:04:17 +0100327 if ((!ref_next(ref2)) != (ref2 == jeb->last_node)) {
328 JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next at %#08x (mem %p), last_node is at %#08x (mem %p).\n",
329 ref_offset(ref2), ref2, ref_offset(ref_next(ref2)), ref_next(ref2),
330 ref_offset(jeb->last_node), jeb->last_node);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100331 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100332 }
David Woodhouse99988f72006-05-24 09:04:17 +0100333 ref2 = ref_next(ref2);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100334 }
335
336 if (my_used_size != jeb->used_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100337 JFFS2_ERROR("Calculated used size %#08x != stored used size %#08x.\n",
338 my_used_size, jeb->used_size);
339 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100340 }
341
342 if (my_unchecked_size != jeb->unchecked_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100343 JFFS2_ERROR("Calculated unchecked size %#08x != stored unchecked size %#08x.\n",
344 my_unchecked_size, jeb->unchecked_size);
345 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100346 }
347
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100348#if 0
349 /* This should work when we implement ref->__totlen elemination */
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100350 if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100351 JFFS2_ERROR("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100352 my_dirty_size, jeb->dirty_size + jeb->wasted_size);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100353 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100354 }
355
356 if (jeb->free_size == 0
357 && my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100358 JFFS2_ERROR("The sum of all nodes in block (%#x) != size of block (%#x)\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100359 my_used_size + my_unchecked_size + my_dirty_size,
360 c->sector_size);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100361 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100362 }
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100363#endif
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100364
David Woodhouse85a62db2008-04-23 01:17:51 +0100365 if (!(c->flags & (JFFS2_SB_FLAG_BUILDING|JFFS2_SB_FLAG_SCANNING)))
366 __jffs2_dbg_superblock_counts(c);
367
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100368 return;
369
370error:
371 __jffs2_dbg_dump_node_refs_nolock(c, jeb);
372 __jffs2_dbg_dump_jeb_nolock(jeb);
373 __jffs2_dbg_dump_block_lists_nolock(c);
374 BUG();
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000375
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100376}
377#endif /* JFFS2_DBG_PARANOIA_CHECKS */
378
379#if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100380/*
381 * Dump the node_refs of the 'jeb' JFFS2 eraseblock.
382 */
383void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100384__jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c,
385 struct jffs2_eraseblock *jeb)
386{
387 spin_lock(&c->erase_completion_lock);
388 __jffs2_dbg_dump_node_refs_nolock(c, jeb);
389 spin_unlock(&c->erase_completion_lock);
390}
391
392void
393__jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c,
394 struct jffs2_eraseblock *jeb)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100395{
396 struct jffs2_raw_node_ref *ref;
397 int i = 0;
398
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100399 printk(JFFS2_DBG_MSG_PREFIX " Dump node_refs of the eraseblock %#08x\n", jeb->offset);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100400 if (!jeb->first_node) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100401 printk(JFFS2_DBG_MSG_PREFIX " no nodes in the eraseblock %#08x\n", jeb->offset);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100402 return;
403 }
404
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100405 printk(JFFS2_DBG);
David Woodhouse99988f72006-05-24 09:04:17 +0100406 for (ref = jeb->first_node; ; ref = ref_next(ref)) {
David Woodhouse27e6b8e2008-04-23 01:25:33 +0100407 printk("%#08x", ref_offset(ref));
408#ifdef TEST_TOTLEN
409 printk("(%x)", ref->__totlen);
410#endif
David Woodhouse99988f72006-05-24 09:04:17 +0100411 if (ref_next(ref))
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100412 printk("->");
413 else
414 break;
415 if (++i == 4) {
416 i = 0;
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100417 printk("\n" JFFS2_DBG);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100418 }
419 }
420 printk("\n");
421}
422
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100423/*
424 * Dump an eraseblock's space accounting.
425 */
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100426void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100427__jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100428{
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100429 spin_lock(&c->erase_completion_lock);
430 __jffs2_dbg_dump_jeb_nolock(jeb);
431 spin_unlock(&c->erase_completion_lock);
432}
433
434void
435__jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb)
436{
437 if (!jeb)
438 return;
439
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100440 printk(JFFS2_DBG_MSG_PREFIX " dump space accounting for the eraseblock at %#08x:\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100441 jeb->offset);
442
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100443 printk(JFFS2_DBG "used_size: %#08x\n", jeb->used_size);
444 printk(JFFS2_DBG "dirty_size: %#08x\n", jeb->dirty_size);
445 printk(JFFS2_DBG "wasted_size: %#08x\n", jeb->wasted_size);
446 printk(JFFS2_DBG "unchecked_size: %#08x\n", jeb->unchecked_size);
447 printk(JFFS2_DBG "free_size: %#08x\n", jeb->free_size);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100448}
449
450void
451__jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c)
452{
453 spin_lock(&c->erase_completion_lock);
454 __jffs2_dbg_dump_block_lists_nolock(c);
455 spin_unlock(&c->erase_completion_lock);
456}
457
458void
459__jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c)
460{
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100461 printk(JFFS2_DBG_MSG_PREFIX " dump JFFS2 blocks lists:\n");
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000462
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100463 printk(JFFS2_DBG "flash_size: %#08x\n", c->flash_size);
464 printk(JFFS2_DBG "used_size: %#08x\n", c->used_size);
465 printk(JFFS2_DBG "dirty_size: %#08x\n", c->dirty_size);
466 printk(JFFS2_DBG "wasted_size: %#08x\n", c->wasted_size);
467 printk(JFFS2_DBG "unchecked_size: %#08x\n", c->unchecked_size);
468 printk(JFFS2_DBG "free_size: %#08x\n", c->free_size);
469 printk(JFFS2_DBG "erasing_size: %#08x\n", c->erasing_size);
470 printk(JFFS2_DBG "bad_size: %#08x\n", c->bad_size);
471 printk(JFFS2_DBG "sector_size: %#08x\n", c->sector_size);
472 printk(JFFS2_DBG "jffs2_reserved_blocks size: %#08x\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100473 c->sector_size * c->resv_blocks_write);
474
475 if (c->nextblock)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100476 printk(JFFS2_DBG "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100477 c->nextblock->offset, c->nextblock->used_size,
478 c->nextblock->dirty_size, c->nextblock->wasted_size,
479 c->nextblock->unchecked_size, c->nextblock->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100480 else
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100481 printk(JFFS2_DBG "nextblock: NULL\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100482
483 if (c->gcblock)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100484 printk(JFFS2_DBG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100485 c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size,
486 c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100487 else
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100488 printk(JFFS2_DBG "gcblock: NULL\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100489
490 if (list_empty(&c->clean_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100491 printk(JFFS2_DBG "clean_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100492 } else {
493 struct list_head *this;
494 int numblocks = 0;
495 uint32_t dirty = 0;
496
497 list_for_each(this, &c->clean_list) {
498 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
499 numblocks ++;
500 dirty += jeb->wasted_size;
501 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100502 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 +0100503 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
504 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100505 }
506 }
507
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100508 printk (JFFS2_DBG "Contains %d blocks with total wasted size %u, average wasted size: %u\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100509 numblocks, dirty, dirty / numblocks);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100510 }
511
512 if (list_empty(&c->very_dirty_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100513 printk(JFFS2_DBG "very_dirty_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100514 } else {
515 struct list_head *this;
516 int numblocks = 0;
517 uint32_t dirty = 0;
518
519 list_for_each(this, &c->very_dirty_list) {
520 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
521
522 numblocks ++;
523 dirty += jeb->dirty_size;
524 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100525 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 +0100526 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
527 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100528 }
529 }
530
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100531 printk (JFFS2_DBG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100532 numblocks, dirty, dirty / numblocks);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100533 }
534
535 if (list_empty(&c->dirty_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100536 printk(JFFS2_DBG "dirty_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100537 } else {
538 struct list_head *this;
539 int numblocks = 0;
540 uint32_t dirty = 0;
541
542 list_for_each(this, &c->dirty_list) {
543 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
544
545 numblocks ++;
546 dirty += jeb->dirty_size;
547 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100548 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 +0100549 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
550 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100551 }
552 }
553
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100554 printk (JFFS2_DBG "contains %d blocks with total dirty size %u, average dirty size: %u\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100555 numblocks, dirty, dirty / numblocks);
556 }
557
558 if (list_empty(&c->erasable_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100559 printk(JFFS2_DBG "erasable_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100560 } else {
561 struct list_head *this;
562
563 list_for_each(this, &c->erasable_list) {
564 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
565
566 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100567 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 +0100568 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
569 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100570 }
571 }
572 }
573
574 if (list_empty(&c->erasing_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100575 printk(JFFS2_DBG "erasing_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100576 } else {
577 struct list_head *this;
578
579 list_for_each(this, &c->erasing_list) {
580 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
581
582 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100583 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 +0100584 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
585 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100586 }
587 }
588 }
David Woodhousee2bc3222008-04-23 14:15:24 +0100589 if (list_empty(&c->erase_checking_list)) {
590 printk(JFFS2_DBG "erase_checking_list: empty\n");
591 } else {
592 struct list_head *this;
593
594 list_for_each(this, &c->erase_checking_list) {
595 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
596
597 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
598 printk(JFFS2_DBG "erase_checking_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
599 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
600 jeb->unchecked_size, jeb->free_size);
601 }
602 }
603 }
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100604
605 if (list_empty(&c->erase_pending_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100606 printk(JFFS2_DBG "erase_pending_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100607 } else {
608 struct list_head *this;
609
610 list_for_each(this, &c->erase_pending_list) {
611 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
612
613 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100614 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 +0100615 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
616 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100617 }
618 }
619 }
620
621 if (list_empty(&c->erasable_pending_wbuf_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100622 printk(JFFS2_DBG "erasable_pending_wbuf_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100623 } else {
624 struct list_head *this;
625
626 list_for_each(this, &c->erasable_pending_wbuf_list) {
627 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
628
629 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100630 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 +0100631 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
632 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100633 }
634 }
635 }
636
637 if (list_empty(&c->free_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100638 printk(JFFS2_DBG "free_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100639 } else {
640 struct list_head *this;
641
642 list_for_each(this, &c->free_list) {
643 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
644
645 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100646 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 +0100647 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
648 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100649 }
650 }
651 }
652
653 if (list_empty(&c->bad_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100654 printk(JFFS2_DBG "bad_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100655 } else {
656 struct list_head *this;
657
658 list_for_each(this, &c->bad_list) {
659 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
660
661 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100662 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 +0100663 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
664 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100665 }
666 }
667 }
668
669 if (list_empty(&c->bad_used_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100670 printk(JFFS2_DBG "bad_used_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100671 } else {
672 struct list_head *this;
673
674 list_for_each(this, &c->bad_used_list) {
675 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
676
677 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100678 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 +0100679 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
680 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100681 }
682 }
683 }
684}
685
686void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100687__jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f)
688{
David Woodhouseced22072008-04-22 15:13:40 +0100689 mutex_lock(&f->sem);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100690 jffs2_dbg_dump_fragtree_nolock(f);
David Woodhouseced22072008-04-22 15:13:40 +0100691 mutex_unlock(&f->sem);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100692}
693
694void
695__jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100696{
697 struct jffs2_node_frag *this = frag_first(&f->fragtree);
698 uint32_t lastofs = 0;
699 int buggy = 0;
700
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100701 printk(JFFS2_DBG_MSG_PREFIX " dump fragtree of ino #%u\n", f->inocache->ino);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100702 while(this) {
703 if (this->node)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100704 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 +0100705 this->ofs, this->ofs+this->size, ref_offset(this->node->raw),
706 ref_flags(this->node->raw), this, frag_left(this), frag_right(this),
707 frag_parent(this));
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100708 else
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100709 printk(JFFS2_DBG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100710 this->ofs, this->ofs+this->size, this, frag_left(this),
711 frag_right(this), frag_parent(this));
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100712 if (this->ofs != lastofs)
713 buggy = 1;
714 lastofs = this->ofs + this->size;
715 this = frag_next(this);
716 }
717
718 if (f->metadata)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100719 printk(JFFS2_DBG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100720
721 if (buggy) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100722 JFFS2_ERROR("frag tree got a hole in it.\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100723 BUG();
724 }
725}
726
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100727#define JFFS2_BUFDUMP_BYTES_PER_LINE 32
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100728void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100729__jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100730{
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100731 int skip;
732 int i;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000733
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100734 printk(JFFS2_DBG_MSG_PREFIX " dump from offset %#08x to offset %#08x (%x bytes).\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100735 offs, offs + len, len);
736 i = skip = offs % JFFS2_BUFDUMP_BYTES_PER_LINE;
737 offs = offs & ~(JFFS2_BUFDUMP_BYTES_PER_LINE - 1);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000738
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100739 if (skip != 0)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100740 printk(JFFS2_DBG "%#08x: ", offs);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000741
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100742 while (skip--)
743 printk(" ");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100744
745 while (i < len) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100746 if ((i % JFFS2_BUFDUMP_BYTES_PER_LINE) == 0 && i != len -1) {
747 if (i != 0)
748 printk("\n");
749 offs += JFFS2_BUFDUMP_BYTES_PER_LINE;
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100750 printk(JFFS2_DBG "%0#8x: ", offs);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100751 }
752
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100753 printk("%02x ", buf[i]);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000754
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100755 i += 1;
756 }
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100757
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100758 printk("\n");
759}
760
761/*
762 * Dump a JFFS2 node.
763 */
764void
765__jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs)
766{
767 union jffs2_node_union node;
768 int len = sizeof(union jffs2_node_union);
769 size_t retlen;
770 uint32_t crc;
771 int ret;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000772
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100773 printk(JFFS2_DBG_MSG_PREFIX " dump node at offset %#08x.\n", ofs);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100774
775 ret = jffs2_flash_read(c, ofs, len, &retlen, (unsigned char *)&node);
776 if (ret || (retlen != len)) {
777 JFFS2_ERROR("read %d bytes failed or short. ret %d, retlen %zd.\n",
778 len, ret, retlen);
779 return;
780 }
781
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100782 printk(JFFS2_DBG "magic:\t%#04x\n", je16_to_cpu(node.u.magic));
783 printk(JFFS2_DBG "nodetype:\t%#04x\n", je16_to_cpu(node.u.nodetype));
784 printk(JFFS2_DBG "totlen:\t%#08x\n", je32_to_cpu(node.u.totlen));
785 printk(JFFS2_DBG "hdr_crc:\t%#08x\n", je32_to_cpu(node.u.hdr_crc));
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000786
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100787 crc = crc32(0, &node.u, sizeof(node.u) - 4);
788 if (crc != je32_to_cpu(node.u.hdr_crc)) {
789 JFFS2_ERROR("wrong common header CRC.\n");
790 return;
791 }
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000792
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100793 if (je16_to_cpu(node.u.magic) != JFFS2_MAGIC_BITMASK &&
794 je16_to_cpu(node.u.magic) != JFFS2_OLD_MAGIC_BITMASK)
795 {
796 JFFS2_ERROR("wrong node magic: %#04x instead of %#04x.\n",
797 je16_to_cpu(node.u.magic), JFFS2_MAGIC_BITMASK);
798 return;
799 }
800
801 switch(je16_to_cpu(node.u.nodetype)) {
802
803 case JFFS2_NODETYPE_INODE:
804
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100805 printk(JFFS2_DBG "the node is inode node\n");
806 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.i.ino));
807 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.i.version));
808 printk(JFFS2_DBG "mode:\t%#08x\n", node.i.mode.m);
809 printk(JFFS2_DBG "uid:\t%#04x\n", je16_to_cpu(node.i.uid));
810 printk(JFFS2_DBG "gid:\t%#04x\n", je16_to_cpu(node.i.gid));
811 printk(JFFS2_DBG "isize:\t%#08x\n", je32_to_cpu(node.i.isize));
812 printk(JFFS2_DBG "atime:\t%#08x\n", je32_to_cpu(node.i.atime));
813 printk(JFFS2_DBG "mtime:\t%#08x\n", je32_to_cpu(node.i.mtime));
814 printk(JFFS2_DBG "ctime:\t%#08x\n", je32_to_cpu(node.i.ctime));
815 printk(JFFS2_DBG "offset:\t%#08x\n", je32_to_cpu(node.i.offset));
816 printk(JFFS2_DBG "csize:\t%#08x\n", je32_to_cpu(node.i.csize));
817 printk(JFFS2_DBG "dsize:\t%#08x\n", je32_to_cpu(node.i.dsize));
818 printk(JFFS2_DBG "compr:\t%#02x\n", node.i.compr);
819 printk(JFFS2_DBG "usercompr:\t%#02x\n", node.i.usercompr);
820 printk(JFFS2_DBG "flags:\t%#04x\n", je16_to_cpu(node.i.flags));
821 printk(JFFS2_DBG "data_crc:\t%#08x\n", je32_to_cpu(node.i.data_crc));
822 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.i.node_crc));
823
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000824 crc = crc32(0, &node.i, sizeof(node.i) - 8);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100825 if (crc != je32_to_cpu(node.i.node_crc)) {
826 JFFS2_ERROR("wrong node header CRC.\n");
827 return;
828 }
829 break;
830
831 case JFFS2_NODETYPE_DIRENT:
832
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100833 printk(JFFS2_DBG "the node is dirent node\n");
834 printk(JFFS2_DBG "pino:\t%#08x\n", je32_to_cpu(node.d.pino));
835 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.d.version));
836 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.d.ino));
837 printk(JFFS2_DBG "mctime:\t%#08x\n", je32_to_cpu(node.d.mctime));
838 printk(JFFS2_DBG "nsize:\t%#02x\n", node.d.nsize);
839 printk(JFFS2_DBG "type:\t%#02x\n", node.d.type);
840 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.d.node_crc));
841 printk(JFFS2_DBG "name_crc:\t%#08x\n", je32_to_cpu(node.d.name_crc));
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000842
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100843 node.d.name[node.d.nsize] = '\0';
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100844 printk(JFFS2_DBG "name:\t\"%s\"\n", node.d.name);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100845
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000846 crc = crc32(0, &node.d, sizeof(node.d) - 8);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100847 if (crc != je32_to_cpu(node.d.node_crc)) {
848 JFFS2_ERROR("wrong node header CRC.\n");
849 return;
850 }
851 break;
852
853 default:
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100854 printk(JFFS2_DBG "node type is unknown\n");
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100855 break;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100856 }
857}
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100858#endif /* JFFS2_DBG_DUMPS || JFFS2_DBG_PARANOIA_CHECKS */