OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [fs/] [jffs2/] [current/] [src/] [debug.c] - Blame information for rev 838

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.