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