blob: e0b76c87a91af298712a5ebc06b3ac7e8a953238 [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.
David Woodhouse6088c052010-08-08 14:15:22 +01005 * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +01006 *
7 * Created by David Woodhouse <dwmw2@infradead.org>
8 *
9 * For licensing information, see the file 'LICENCE' in this directory.
10 *
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010011 */
David Woodhousec00c3102007-04-25 14:16:47 +010012
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010013#include <linux/kernel.h>
Andrew Lunn737b7662005-07-30 16:29:30 +010014#include <linux/types.h>
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010015#include <linux/pagemap.h>
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010016#include <linux/crc32.h>
17#include <linux/jffs2.h>
Artem B. Bityutskiy733802d2005-09-22 12:25:00 +010018#include <linux/mtd/mtd.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090019#include <linux/slab.h>
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010020#include "nodelist.h"
21#include "debug.h"
22
Artem B. Bityutskiy45ca1b52005-08-05 12:43:47 +010023#ifdef JFFS2_DBG_SANITY_CHECKS
24
25void
26__jffs2_dbg_acct_sanity_check_nolock(struct jffs2_sb_info *c,
27 struct jffs2_eraseblock *jeb)
28{
29 if (unlikely(jeb && jeb->used_size + jeb->dirty_size +
30 jeb->free_size + jeb->wasted_size +
31 jeb->unchecked_size != c->sector_size)) {
32 JFFS2_ERROR("eeep, space accounting for block at 0x%08x is screwed.\n", jeb->offset);
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +010033 JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
34 jeb->free_size, jeb->dirty_size, jeb->used_size,
Artem B. Bityutskiy45ca1b52005-08-05 12:43:47 +010035 jeb->wasted_size, jeb->unchecked_size, c->sector_size);
36 BUG();
37 }
38
39 if (unlikely(c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size
40 + c->wasted_size + c->unchecked_size != c->flash_size)) {
41 JFFS2_ERROR("eeep, space accounting superblock info is screwed.\n");
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +010042 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 +010043 c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size,
44 c->wasted_size, c->unchecked_size, c->flash_size);
45 BUG();
46 }
47}
48
49void
50__jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c,
51 struct jffs2_eraseblock *jeb)
52{
53 spin_lock(&c->erase_completion_lock);
54 jffs2_dbg_acct_sanity_check_nolock(c, jeb);
55 spin_unlock(&c->erase_completion_lock);
56}
57
58#endif /* JFFS2_DBG_SANITY_CHECKS */
59
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010060#ifdef JFFS2_DBG_PARANOIA_CHECKS
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010061/*
62 * Check the fragtree.
63 */
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010064void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010065__jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f)
66{
David Woodhouseced22072008-04-22 15:13:40 +010067 mutex_lock(&f->sem);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010068 __jffs2_dbg_fragtree_paranoia_check_nolock(f);
David Woodhouseced22072008-04-22 15:13:40 +010069 mutex_unlock(&f->sem);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010070}
Thomas Gleixner182ec4e2005-11-07 11:16:07 +000071
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010072void
73__jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010074{
75 struct jffs2_node_frag *frag;
76 int bitched = 0;
77
78 for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
79 struct jffs2_full_dnode *fn = frag->node;
80
81 if (!fn || !fn->raw)
82 continue;
83
84 if (ref_flags(fn->raw) == REF_PRISTINE) {
85 if (fn->frags > 1) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +010086 JFFS2_ERROR("REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2.\n",
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +010087 ref_offset(fn->raw), fn->frags);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +010088 bitched = 1;
89 }
90
91 /* A hole node which isn't multi-page should be garbage-collected
92 and merged anyway, so we just check for the frag size here,
93 rather than mucking around with actually reading the node
94 and checking the compression type, which is the real way
95 to tell a hole node. */
96 if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag)
97 && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +010098 JFFS2_ERROR("REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2.\n",
99 ref_offset(fn->raw));
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100100 bitched = 1;
101 }
102
103 if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag)
104 && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100105 JFFS2_ERROR("REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2.\n",
106 ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100107 bitched = 1;
108 }
109 }
110 }
111
112 if (bitched) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100113 JFFS2_ERROR("fragtree is corrupted.\n");
114 __jffs2_dbg_dump_fragtree_nolock(f);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100115 BUG();
116 }
117}
118
119/*
120 * Check if the flash contains all 0xFF before we start writing.
121 */
122void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100123__jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
124 uint32_t ofs, int len)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100125{
126 size_t retlen;
127 int ret, i;
128 unsigned char *buf;
129
130 buf = kmalloc(len, GFP_KERNEL);
131 if (!buf)
132 return;
133
134 ret = jffs2_flash_read(c, ofs, len, &retlen, buf);
135 if (ret || (retlen != len)) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100136 JFFS2_WARNING("read %d bytes failed or short. ret %d, retlen %zd.\n",
137 len, ret, retlen);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100138 kfree(buf);
139 return;
140 }
141
142 ret = 0;
143 for (i = 0; i < len; i++)
144 if (buf[i] != 0xff)
145 ret = 1;
146
147 if (ret) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100148 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",
149 ofs, ofs + i);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100150 __jffs2_dbg_dump_buffer(buf, len, ofs);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100151 kfree(buf);
152 BUG();
153 }
154
155 kfree(buf);
156}
157
David Woodhouse85a62db2008-04-23 01:17:51 +0100158void __jffs2_dbg_superblock_counts(struct jffs2_sb_info *c)
159{
160 struct jffs2_eraseblock *jeb;
161 uint32_t free = 0, dirty = 0, used = 0, wasted = 0,
162 erasing = 0, bad = 0, unchecked = 0;
163 int nr_counted = 0;
164 int dump = 0;
165
166 if (c->gcblock) {
167 nr_counted++;
168 free += c->gcblock->free_size;
169 dirty += c->gcblock->dirty_size;
170 used += c->gcblock->used_size;
171 wasted += c->gcblock->wasted_size;
172 unchecked += c->gcblock->unchecked_size;
173 }
174 if (c->nextblock) {
175 nr_counted++;
176 free += c->nextblock->free_size;
177 dirty += c->nextblock->dirty_size;
178 used += c->nextblock->used_size;
179 wasted += c->nextblock->wasted_size;
180 unchecked += c->nextblock->unchecked_size;
181 }
182 list_for_each_entry(jeb, &c->clean_list, list) {
183 nr_counted++;
184 free += jeb->free_size;
185 dirty += jeb->dirty_size;
186 used += jeb->used_size;
187 wasted += jeb->wasted_size;
188 unchecked += jeb->unchecked_size;
189 }
190 list_for_each_entry(jeb, &c->very_dirty_list, list) {
191 nr_counted++;
192 free += jeb->free_size;
193 dirty += jeb->dirty_size;
194 used += jeb->used_size;
195 wasted += jeb->wasted_size;
196 unchecked += jeb->unchecked_size;
197 }
198 list_for_each_entry(jeb, &c->dirty_list, list) {
199 nr_counted++;
200 free += jeb->free_size;
201 dirty += jeb->dirty_size;
202 used += jeb->used_size;
203 wasted += jeb->wasted_size;
204 unchecked += jeb->unchecked_size;
205 }
206 list_for_each_entry(jeb, &c->erasable_list, list) {
207 nr_counted++;
208 free += jeb->free_size;
209 dirty += jeb->dirty_size;
210 used += jeb->used_size;
211 wasted += jeb->wasted_size;
212 unchecked += jeb->unchecked_size;
213 }
214 list_for_each_entry(jeb, &c->erasable_pending_wbuf_list, list) {
215 nr_counted++;
216 free += jeb->free_size;
217 dirty += jeb->dirty_size;
218 used += jeb->used_size;
219 wasted += jeb->wasted_size;
220 unchecked += jeb->unchecked_size;
221 }
222 list_for_each_entry(jeb, &c->erase_pending_list, list) {
223 nr_counted++;
224 free += jeb->free_size;
225 dirty += jeb->dirty_size;
226 used += jeb->used_size;
227 wasted += jeb->wasted_size;
228 unchecked += jeb->unchecked_size;
229 }
230 list_for_each_entry(jeb, &c->free_list, list) {
231 nr_counted++;
232 free += jeb->free_size;
233 dirty += jeb->dirty_size;
234 used += jeb->used_size;
235 wasted += jeb->wasted_size;
236 unchecked += jeb->unchecked_size;
237 }
238 list_for_each_entry(jeb, &c->bad_used_list, list) {
239 nr_counted++;
240 free += jeb->free_size;
241 dirty += jeb->dirty_size;
242 used += jeb->used_size;
243 wasted += jeb->wasted_size;
244 unchecked += jeb->unchecked_size;
245 }
246
247 list_for_each_entry(jeb, &c->erasing_list, list) {
248 nr_counted++;
249 erasing += c->sector_size;
250 }
David Woodhousee2bc3222008-04-23 14:15:24 +0100251 list_for_each_entry(jeb, &c->erase_checking_list, list) {
252 nr_counted++;
253 erasing += c->sector_size;
254 }
David Woodhouse85a62db2008-04-23 01:17:51 +0100255 list_for_each_entry(jeb, &c->erase_complete_list, list) {
256 nr_counted++;
257 erasing += c->sector_size;
258 }
259 list_for_each_entry(jeb, &c->bad_list, list) {
260 nr_counted++;
261 bad += c->sector_size;
262 }
263
264#define check(sz) \
265 if (sz != c->sz##_size) { \
266 printk(KERN_WARNING #sz "_size mismatch counted 0x%x, c->" #sz "_size 0x%x\n", \
267 sz, c->sz##_size); \
268 dump = 1; \
269 }
270 check(free);
271 check(dirty);
272 check(used);
273 check(wasted);
274 check(unchecked);
275 check(bad);
276 check(erasing);
277#undef check
278
279 if (nr_counted != c->nr_blocks) {
280 printk(KERN_WARNING "%s counted only 0x%x blocks of 0x%x. Where are the others?\n",
281 __func__, nr_counted, c->nr_blocks);
282 dump = 1;
283 }
284
285 if (dump) {
286 __jffs2_dbg_dump_block_lists_nolock(c);
287 BUG();
288 }
289}
290
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100291/*
292 * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
293 */
294void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100295__jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c,
296 struct jffs2_eraseblock *jeb)
297{
298 spin_lock(&c->erase_completion_lock);
299 __jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
300 spin_unlock(&c->erase_completion_lock);
301}
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000302
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100303void
304__jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
305 struct jffs2_eraseblock *jeb)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100306{
307 uint32_t my_used_size = 0;
308 uint32_t my_unchecked_size = 0;
309 uint32_t my_dirty_size = 0;
310 struct jffs2_raw_node_ref *ref2 = jeb->first_node;
311
312 while (ref2) {
313 uint32_t totlen = ref_totlen(c, jeb, ref2);
314
Kyungmin Parkabb536e2006-12-22 16:39:30 +0900315 if (ref_offset(ref2) < jeb->offset ||
316 ref_offset(ref2) > jeb->offset + c->sector_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100317 JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100318 ref_offset(ref2), jeb->offset);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100319 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100320
321 }
322 if (ref_flags(ref2) == REF_UNCHECKED)
323 my_unchecked_size += totlen;
324 else if (!ref_obsolete(ref2))
325 my_used_size += totlen;
326 else
327 my_dirty_size += totlen;
328
David Woodhouse99988f72006-05-24 09:04:17 +0100329 if ((!ref_next(ref2)) != (ref2 == jeb->last_node)) {
330 JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next at %#08x (mem %p), last_node is at %#08x (mem %p).\n",
331 ref_offset(ref2), ref2, ref_offset(ref_next(ref2)), ref_next(ref2),
332 ref_offset(jeb->last_node), jeb->last_node);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100333 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100334 }
David Woodhouse99988f72006-05-24 09:04:17 +0100335 ref2 = ref_next(ref2);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100336 }
337
338 if (my_used_size != jeb->used_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100339 JFFS2_ERROR("Calculated used size %#08x != stored used size %#08x.\n",
340 my_used_size, jeb->used_size);
341 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100342 }
343
344 if (my_unchecked_size != jeb->unchecked_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100345 JFFS2_ERROR("Calculated unchecked size %#08x != stored unchecked size %#08x.\n",
346 my_unchecked_size, jeb->unchecked_size);
347 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100348 }
349
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100350#if 0
351 /* This should work when we implement ref->__totlen elemination */
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100352 if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100353 JFFS2_ERROR("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100354 my_dirty_size, jeb->dirty_size + jeb->wasted_size);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100355 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100356 }
357
358 if (jeb->free_size == 0
359 && my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100360 JFFS2_ERROR("The sum of all nodes in block (%#x) != size of block (%#x)\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100361 my_used_size + my_unchecked_size + my_dirty_size,
362 c->sector_size);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100363 goto error;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100364 }
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100365#endif
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100366
David Woodhouse85a62db2008-04-23 01:17:51 +0100367 if (!(c->flags & (JFFS2_SB_FLAG_BUILDING|JFFS2_SB_FLAG_SCANNING)))
368 __jffs2_dbg_superblock_counts(c);
369
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100370 return;
371
372error:
373 __jffs2_dbg_dump_node_refs_nolock(c, jeb);
374 __jffs2_dbg_dump_jeb_nolock(jeb);
375 __jffs2_dbg_dump_block_lists_nolock(c);
376 BUG();
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000377
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100378}
379#endif /* JFFS2_DBG_PARANOIA_CHECKS */
380
381#if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100382/*
383 * Dump the node_refs of the 'jeb' JFFS2 eraseblock.
384 */
385void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100386__jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c,
387 struct jffs2_eraseblock *jeb)
388{
389 spin_lock(&c->erase_completion_lock);
390 __jffs2_dbg_dump_node_refs_nolock(c, jeb);
391 spin_unlock(&c->erase_completion_lock);
392}
393
394void
395__jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c,
396 struct jffs2_eraseblock *jeb)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100397{
398 struct jffs2_raw_node_ref *ref;
399 int i = 0;
400
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100401 printk(JFFS2_DBG_MSG_PREFIX " Dump node_refs of the eraseblock %#08x\n", jeb->offset);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100402 if (!jeb->first_node) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100403 printk(JFFS2_DBG_MSG_PREFIX " no nodes in the eraseblock %#08x\n", jeb->offset);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100404 return;
405 }
406
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100407 printk(JFFS2_DBG);
David Woodhouse99988f72006-05-24 09:04:17 +0100408 for (ref = jeb->first_node; ; ref = ref_next(ref)) {
David Woodhouse27e6b8e2008-04-23 01:25:33 +0100409 printk("%#08x", ref_offset(ref));
410#ifdef TEST_TOTLEN
411 printk("(%x)", ref->__totlen);
412#endif
David Woodhouse99988f72006-05-24 09:04:17 +0100413 if (ref_next(ref))
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100414 printk("->");
415 else
416 break;
417 if (++i == 4) {
418 i = 0;
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100419 printk("\n" JFFS2_DBG);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100420 }
421 }
422 printk("\n");
423}
424
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100425/*
426 * Dump an eraseblock's space accounting.
427 */
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100428void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100429__jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100430{
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100431 spin_lock(&c->erase_completion_lock);
432 __jffs2_dbg_dump_jeb_nolock(jeb);
433 spin_unlock(&c->erase_completion_lock);
434}
435
436void
437__jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb)
438{
439 if (!jeb)
440 return;
441
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100442 printk(JFFS2_DBG_MSG_PREFIX " dump space accounting for the eraseblock at %#08x:\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100443 jeb->offset);
444
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100445 printk(JFFS2_DBG "used_size: %#08x\n", jeb->used_size);
446 printk(JFFS2_DBG "dirty_size: %#08x\n", jeb->dirty_size);
447 printk(JFFS2_DBG "wasted_size: %#08x\n", jeb->wasted_size);
448 printk(JFFS2_DBG "unchecked_size: %#08x\n", jeb->unchecked_size);
449 printk(JFFS2_DBG "free_size: %#08x\n", jeb->free_size);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100450}
451
452void
453__jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c)
454{
455 spin_lock(&c->erase_completion_lock);
456 __jffs2_dbg_dump_block_lists_nolock(c);
457 spin_unlock(&c->erase_completion_lock);
458}
459
460void
461__jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c)
462{
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100463 printk(JFFS2_DBG_MSG_PREFIX " dump JFFS2 blocks lists:\n");
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000464
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100465 printk(JFFS2_DBG "flash_size: %#08x\n", c->flash_size);
466 printk(JFFS2_DBG "used_size: %#08x\n", c->used_size);
467 printk(JFFS2_DBG "dirty_size: %#08x\n", c->dirty_size);
468 printk(JFFS2_DBG "wasted_size: %#08x\n", c->wasted_size);
469 printk(JFFS2_DBG "unchecked_size: %#08x\n", c->unchecked_size);
470 printk(JFFS2_DBG "free_size: %#08x\n", c->free_size);
471 printk(JFFS2_DBG "erasing_size: %#08x\n", c->erasing_size);
472 printk(JFFS2_DBG "bad_size: %#08x\n", c->bad_size);
473 printk(JFFS2_DBG "sector_size: %#08x\n", c->sector_size);
474 printk(JFFS2_DBG "jffs2_reserved_blocks size: %#08x\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100475 c->sector_size * c->resv_blocks_write);
476
477 if (c->nextblock)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100478 printk(JFFS2_DBG "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100479 c->nextblock->offset, c->nextblock->used_size,
480 c->nextblock->dirty_size, c->nextblock->wasted_size,
481 c->nextblock->unchecked_size, c->nextblock->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100482 else
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100483 printk(JFFS2_DBG "nextblock: NULL\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100484
485 if (c->gcblock)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100486 printk(JFFS2_DBG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100487 c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size,
488 c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100489 else
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100490 printk(JFFS2_DBG "gcblock: NULL\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100491
492 if (list_empty(&c->clean_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100493 printk(JFFS2_DBG "clean_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100494 } else {
495 struct list_head *this;
496 int numblocks = 0;
497 uint32_t dirty = 0;
498
499 list_for_each(this, &c->clean_list) {
500 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
501 numblocks ++;
502 dirty += jeb->wasted_size;
503 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100504 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 +0100505 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
506 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100507 }
508 }
509
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100510 printk (JFFS2_DBG "Contains %d blocks with total wasted size %u, average wasted size: %u\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100511 numblocks, dirty, dirty / numblocks);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100512 }
513
514 if (list_empty(&c->very_dirty_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100515 printk(JFFS2_DBG "very_dirty_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100516 } else {
517 struct list_head *this;
518 int numblocks = 0;
519 uint32_t dirty = 0;
520
521 list_for_each(this, &c->very_dirty_list) {
522 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
523
524 numblocks ++;
525 dirty += jeb->dirty_size;
526 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100527 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 +0100528 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
529 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100530 }
531 }
532
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100533 printk (JFFS2_DBG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100534 numblocks, dirty, dirty / numblocks);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100535 }
536
537 if (list_empty(&c->dirty_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100538 printk(JFFS2_DBG "dirty_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100539 } else {
540 struct list_head *this;
541 int numblocks = 0;
542 uint32_t dirty = 0;
543
544 list_for_each(this, &c->dirty_list) {
545 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
546
547 numblocks ++;
548 dirty += jeb->dirty_size;
549 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100550 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 +0100551 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
552 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100553 }
554 }
555
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100556 printk (JFFS2_DBG "contains %d blocks with total dirty size %u, average dirty size: %u\n",
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100557 numblocks, dirty, dirty / numblocks);
558 }
559
560 if (list_empty(&c->erasable_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100561 printk(JFFS2_DBG "erasable_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100562 } else {
563 struct list_head *this;
564
565 list_for_each(this, &c->erasable_list) {
566 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
567
568 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100569 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 +0100570 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
571 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100572 }
573 }
574 }
575
576 if (list_empty(&c->erasing_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100577 printk(JFFS2_DBG "erasing_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100578 } else {
579 struct list_head *this;
580
581 list_for_each(this, &c->erasing_list) {
582 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
583
584 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100585 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 +0100586 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
587 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100588 }
589 }
590 }
David Woodhousee2bc3222008-04-23 14:15:24 +0100591 if (list_empty(&c->erase_checking_list)) {
592 printk(JFFS2_DBG "erase_checking_list: empty\n");
593 } else {
594 struct list_head *this;
595
596 list_for_each(this, &c->erase_checking_list) {
597 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
598
599 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
600 printk(JFFS2_DBG "erase_checking_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
601 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
602 jeb->unchecked_size, jeb->free_size);
603 }
604 }
605 }
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100606
607 if (list_empty(&c->erase_pending_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100608 printk(JFFS2_DBG "erase_pending_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100609 } else {
610 struct list_head *this;
611
612 list_for_each(this, &c->erase_pending_list) {
613 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
614
615 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100616 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 +0100617 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
618 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100619 }
620 }
621 }
622
623 if (list_empty(&c->erasable_pending_wbuf_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100624 printk(JFFS2_DBG "erasable_pending_wbuf_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100625 } else {
626 struct list_head *this;
627
628 list_for_each(this, &c->erasable_pending_wbuf_list) {
629 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
630
631 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100632 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 +0100633 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
634 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100635 }
636 }
637 }
638
639 if (list_empty(&c->free_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100640 printk(JFFS2_DBG "free_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100641 } else {
642 struct list_head *this;
643
644 list_for_each(this, &c->free_list) {
645 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
646
647 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100648 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 +0100649 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
650 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100651 }
652 }
653 }
654
655 if (list_empty(&c->bad_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100656 printk(JFFS2_DBG "bad_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100657 } else {
658 struct list_head *this;
659
660 list_for_each(this, &c->bad_list) {
661 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
662
663 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100664 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 +0100665 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
666 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100667 }
668 }
669 }
670
671 if (list_empty(&c->bad_used_list)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100672 printk(JFFS2_DBG "bad_used_list: empty\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100673 } else {
674 struct list_head *this;
675
676 list_for_each(this, &c->bad_used_list) {
677 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
678
679 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100680 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 +0100681 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
682 jeb->unchecked_size, jeb->free_size);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100683 }
684 }
685 }
686}
687
688void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100689__jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f)
690{
David Woodhouseced22072008-04-22 15:13:40 +0100691 mutex_lock(&f->sem);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100692 jffs2_dbg_dump_fragtree_nolock(f);
David Woodhouseced22072008-04-22 15:13:40 +0100693 mutex_unlock(&f->sem);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100694}
695
696void
697__jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100698{
699 struct jffs2_node_frag *this = frag_first(&f->fragtree);
700 uint32_t lastofs = 0;
701 int buggy = 0;
702
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100703 printk(JFFS2_DBG_MSG_PREFIX " dump fragtree of ino #%u\n", f->inocache->ino);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100704 while(this) {
705 if (this->node)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100706 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 +0100707 this->ofs, this->ofs+this->size, ref_offset(this->node->raw),
708 ref_flags(this->node->raw), this, frag_left(this), frag_right(this),
709 frag_parent(this));
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100710 else
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100711 printk(JFFS2_DBG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100712 this->ofs, this->ofs+this->size, this, frag_left(this),
713 frag_right(this), frag_parent(this));
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100714 if (this->ofs != lastofs)
715 buggy = 1;
716 lastofs = this->ofs + this->size;
717 this = frag_next(this);
718 }
719
720 if (f->metadata)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100721 printk(JFFS2_DBG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100722
723 if (buggy) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100724 JFFS2_ERROR("frag tree got a hole in it.\n");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100725 BUG();
726 }
727}
728
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100729#define JFFS2_BUFDUMP_BYTES_PER_LINE 32
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100730void
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100731__jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs)
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100732{
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100733 int skip;
734 int i;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000735
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100736 printk(JFFS2_DBG_MSG_PREFIX " dump from offset %#08x to offset %#08x (%x bytes).\n",
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100737 offs, offs + len, len);
738 i = skip = offs % JFFS2_BUFDUMP_BYTES_PER_LINE;
739 offs = offs & ~(JFFS2_BUFDUMP_BYTES_PER_LINE - 1);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000740
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100741 if (skip != 0)
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100742 printk(JFFS2_DBG "%#08x: ", offs);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000743
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100744 while (skip--)
745 printk(" ");
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100746
747 while (i < len) {
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100748 if ((i % JFFS2_BUFDUMP_BYTES_PER_LINE) == 0 && i != len -1) {
749 if (i != 0)
750 printk("\n");
751 offs += JFFS2_BUFDUMP_BYTES_PER_LINE;
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100752 printk(JFFS2_DBG "%0#8x: ", offs);
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100753 }
754
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100755 printk("%02x ", buf[i]);
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000756
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100757 i += 1;
758 }
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100759
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100760 printk("\n");
761}
762
763/*
764 * Dump a JFFS2 node.
765 */
766void
767__jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs)
768{
769 union jffs2_node_union node;
770 int len = sizeof(union jffs2_node_union);
771 size_t retlen;
772 uint32_t crc;
773 int ret;
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000774
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100775 printk(JFFS2_DBG_MSG_PREFIX " dump node at offset %#08x.\n", ofs);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100776
777 ret = jffs2_flash_read(c, ofs, len, &retlen, (unsigned char *)&node);
778 if (ret || (retlen != len)) {
779 JFFS2_ERROR("read %d bytes failed or short. ret %d, retlen %zd.\n",
780 len, ret, retlen);
781 return;
782 }
783
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100784 printk(JFFS2_DBG "magic:\t%#04x\n", je16_to_cpu(node.u.magic));
785 printk(JFFS2_DBG "nodetype:\t%#04x\n", je16_to_cpu(node.u.nodetype));
786 printk(JFFS2_DBG "totlen:\t%#08x\n", je32_to_cpu(node.u.totlen));
787 printk(JFFS2_DBG "hdr_crc:\t%#08x\n", je32_to_cpu(node.u.hdr_crc));
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000788
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100789 crc = crc32(0, &node.u, sizeof(node.u) - 4);
790 if (crc != je32_to_cpu(node.u.hdr_crc)) {
791 JFFS2_ERROR("wrong common header CRC.\n");
792 return;
793 }
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000794
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100795 if (je16_to_cpu(node.u.magic) != JFFS2_MAGIC_BITMASK &&
796 je16_to_cpu(node.u.magic) != JFFS2_OLD_MAGIC_BITMASK)
797 {
798 JFFS2_ERROR("wrong node magic: %#04x instead of %#04x.\n",
799 je16_to_cpu(node.u.magic), JFFS2_MAGIC_BITMASK);
800 return;
801 }
802
803 switch(je16_to_cpu(node.u.nodetype)) {
804
805 case JFFS2_NODETYPE_INODE:
806
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100807 printk(JFFS2_DBG "the node is inode node\n");
808 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.i.ino));
809 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.i.version));
810 printk(JFFS2_DBG "mode:\t%#08x\n", node.i.mode.m);
811 printk(JFFS2_DBG "uid:\t%#04x\n", je16_to_cpu(node.i.uid));
812 printk(JFFS2_DBG "gid:\t%#04x\n", je16_to_cpu(node.i.gid));
813 printk(JFFS2_DBG "isize:\t%#08x\n", je32_to_cpu(node.i.isize));
814 printk(JFFS2_DBG "atime:\t%#08x\n", je32_to_cpu(node.i.atime));
815 printk(JFFS2_DBG "mtime:\t%#08x\n", je32_to_cpu(node.i.mtime));
816 printk(JFFS2_DBG "ctime:\t%#08x\n", je32_to_cpu(node.i.ctime));
817 printk(JFFS2_DBG "offset:\t%#08x\n", je32_to_cpu(node.i.offset));
818 printk(JFFS2_DBG "csize:\t%#08x\n", je32_to_cpu(node.i.csize));
819 printk(JFFS2_DBG "dsize:\t%#08x\n", je32_to_cpu(node.i.dsize));
820 printk(JFFS2_DBG "compr:\t%#02x\n", node.i.compr);
821 printk(JFFS2_DBG "usercompr:\t%#02x\n", node.i.usercompr);
822 printk(JFFS2_DBG "flags:\t%#04x\n", je16_to_cpu(node.i.flags));
823 printk(JFFS2_DBG "data_crc:\t%#08x\n", je32_to_cpu(node.i.data_crc));
824 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.i.node_crc));
825
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000826 crc = crc32(0, &node.i, sizeof(node.i) - 8);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100827 if (crc != je32_to_cpu(node.i.node_crc)) {
828 JFFS2_ERROR("wrong node header CRC.\n");
829 return;
830 }
831 break;
832
833 case JFFS2_NODETYPE_DIRENT:
834
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100835 printk(JFFS2_DBG "the node is dirent node\n");
836 printk(JFFS2_DBG "pino:\t%#08x\n", je32_to_cpu(node.d.pino));
837 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.d.version));
838 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.d.ino));
839 printk(JFFS2_DBG "mctime:\t%#08x\n", je32_to_cpu(node.d.mctime));
840 printk(JFFS2_DBG "nsize:\t%#02x\n", node.d.nsize);
841 printk(JFFS2_DBG "type:\t%#02x\n", node.d.type);
842 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.d.node_crc));
843 printk(JFFS2_DBG "name_crc:\t%#08x\n", je32_to_cpu(node.d.name_crc));
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000844
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100845 node.d.name[node.d.nsize] = '\0';
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100846 printk(JFFS2_DBG "name:\t\"%s\"\n", node.d.name);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100847
Thomas Gleixner182ec4e2005-11-07 11:16:07 +0000848 crc = crc32(0, &node.d, sizeof(node.d) - 8);
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100849 if (crc != je32_to_cpu(node.d.node_crc)) {
850 JFFS2_ERROR("wrong node header CRC.\n");
851 return;
852 }
853 break;
854
855 default:
Artem B. Bityutskiy81e39cf2005-09-14 17:57:35 +0100856 printk(JFFS2_DBG "node type is unknown\n");
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100857 break;
Artem B. Bityutskiy730554d2005-07-17 07:56:26 +0100858 }
859}
Artem B. Bityutskiye0c8e422005-07-24 16:14:17 +0100860#endif /* JFFS2_DBG_DUMPS || JFFS2_DBG_PARANOIA_CHECKS */