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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [fs/] [jffs2/] [debug.c] - Blame information for rev 19

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

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