1730554d9SArtem B. Bityutskiy /*
2730554d9SArtem B. Bityutskiy * JFFS2 -- Journalling Flash File System, Version 2.
3730554d9SArtem B. Bityutskiy *
4c00c310eSDavid Woodhouse * Copyright © 2001-2007 Red Hat, Inc.
56088c058SDavid Woodhouse * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
6730554d9SArtem B. Bityutskiy *
7730554d9SArtem B. Bityutskiy * Created by David Woodhouse <dwmw2@infradead.org>
8730554d9SArtem B. Bityutskiy *
9730554d9SArtem B. Bityutskiy * For licensing information, see the file 'LICENCE' in this directory.
10730554d9SArtem B. Bityutskiy *
11730554d9SArtem B. Bityutskiy */
12c00c310eSDavid Woodhouse
135a528957SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
145a528957SJoe Perches
15730554d9SArtem B. Bityutskiy #include <linux/kernel.h>
16737b7661SAndrew Lunn #include <linux/types.h>
17730554d9SArtem B. Bityutskiy #include <linux/pagemap.h>
18e0c8e42fSArtem B. Bityutskiy #include <linux/crc32.h>
19e0c8e42fSArtem B. Bityutskiy #include <linux/jffs2.h>
20733802d9SArtem B. Bityutskiy #include <linux/mtd/mtd.h>
215a0e3ad6STejun Heo #include <linux/slab.h>
22730554d9SArtem B. Bityutskiy #include "nodelist.h"
23730554d9SArtem B. Bityutskiy #include "debug.h"
24730554d9SArtem B. Bityutskiy
2545ca1b50SArtem B. Bityutskiy #ifdef JFFS2_DBG_SANITY_CHECKS
2645ca1b50SArtem B. Bityutskiy
2745ca1b50SArtem B. Bityutskiy void
__jffs2_dbg_acct_sanity_check_nolock(struct jffs2_sb_info * c,struct jffs2_eraseblock * jeb)2845ca1b50SArtem B. Bityutskiy __jffs2_dbg_acct_sanity_check_nolock(struct jffs2_sb_info *c,
2945ca1b50SArtem B. Bityutskiy struct jffs2_eraseblock *jeb)
3045ca1b50SArtem B. Bityutskiy {
3145ca1b50SArtem B. Bityutskiy if (unlikely(jeb && jeb->used_size + jeb->dirty_size +
3245ca1b50SArtem B. Bityutskiy jeb->free_size + jeb->wasted_size +
3345ca1b50SArtem B. Bityutskiy jeb->unchecked_size != c->sector_size)) {
3445ca1b50SArtem B. Bityutskiy JFFS2_ERROR("eeep, space accounting for block at 0x%08x is screwed.\n", jeb->offset);
3581e39cf0SArtem B. Bityutskiy JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
3681e39cf0SArtem B. Bityutskiy jeb->free_size, jeb->dirty_size, jeb->used_size,
3745ca1b50SArtem B. Bityutskiy jeb->wasted_size, jeb->unchecked_size, c->sector_size);
3845ca1b50SArtem B. Bityutskiy BUG();
3945ca1b50SArtem B. Bityutskiy }
4045ca1b50SArtem B. Bityutskiy
4145ca1b50SArtem B. Bityutskiy if (unlikely(c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size
4245ca1b50SArtem B. Bityutskiy + c->wasted_size + c->unchecked_size != c->flash_size)) {
4345ca1b50SArtem B. Bityutskiy JFFS2_ERROR("eeep, space accounting superblock info is screwed.\n");
4481e39cf0SArtem B. Bityutskiy JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + erasing %#08x + bad %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n",
4545ca1b50SArtem B. Bityutskiy c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size,
4645ca1b50SArtem B. Bityutskiy c->wasted_size, c->unchecked_size, c->flash_size);
4745ca1b50SArtem B. Bityutskiy BUG();
4845ca1b50SArtem B. Bityutskiy }
4945ca1b50SArtem B. Bityutskiy }
5045ca1b50SArtem B. Bityutskiy
5145ca1b50SArtem B. Bityutskiy void
__jffs2_dbg_acct_sanity_check(struct jffs2_sb_info * c,struct jffs2_eraseblock * jeb)5245ca1b50SArtem B. Bityutskiy __jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c,
5345ca1b50SArtem B. Bityutskiy struct jffs2_eraseblock *jeb)
5445ca1b50SArtem B. Bityutskiy {
5545ca1b50SArtem B. Bityutskiy spin_lock(&c->erase_completion_lock);
5645ca1b50SArtem B. Bityutskiy jffs2_dbg_acct_sanity_check_nolock(c, jeb);
5745ca1b50SArtem B. Bityutskiy spin_unlock(&c->erase_completion_lock);
5845ca1b50SArtem B. Bityutskiy }
5945ca1b50SArtem B. Bityutskiy
6045ca1b50SArtem B. Bityutskiy #endif /* JFFS2_DBG_SANITY_CHECKS */
6145ca1b50SArtem B. Bityutskiy
62730554d9SArtem B. Bityutskiy #ifdef JFFS2_DBG_PARANOIA_CHECKS
63e0c8e42fSArtem B. Bityutskiy /*
64e0c8e42fSArtem B. Bityutskiy * Check the fragtree.
65e0c8e42fSArtem B. Bityutskiy */
66e0c8e42fSArtem B. Bityutskiy void
__jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info * f)67e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f)
68e0c8e42fSArtem B. Bityutskiy {
69ced22070SDavid Woodhouse mutex_lock(&f->sem);
70e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_fragtree_paranoia_check_nolock(f);
71ced22070SDavid Woodhouse mutex_unlock(&f->sem);
72e0c8e42fSArtem B. Bityutskiy }
73730554d9SArtem B. Bityutskiy
74730554d9SArtem B. Bityutskiy void
__jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info * f)75e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f)
76730554d9SArtem B. Bityutskiy {
77730554d9SArtem B. Bityutskiy struct jffs2_node_frag *frag;
78730554d9SArtem B. Bityutskiy int bitched = 0;
79730554d9SArtem B. Bityutskiy
80730554d9SArtem B. Bityutskiy for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
81730554d9SArtem B. Bityutskiy struct jffs2_full_dnode *fn = frag->node;
82730554d9SArtem B. Bityutskiy
83730554d9SArtem B. Bityutskiy if (!fn || !fn->raw)
84730554d9SArtem B. Bityutskiy continue;
85730554d9SArtem B. Bityutskiy
86730554d9SArtem B. Bityutskiy if (ref_flags(fn->raw) == REF_PRISTINE) {
87730554d9SArtem B. Bityutskiy if (fn->frags > 1) {
88e0c8e42fSArtem B. Bityutskiy JFFS2_ERROR("REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2.\n",
89730554d9SArtem B. Bityutskiy ref_offset(fn->raw), fn->frags);
90730554d9SArtem B. Bityutskiy bitched = 1;
91730554d9SArtem B. Bityutskiy }
92730554d9SArtem B. Bityutskiy
93730554d9SArtem B. Bityutskiy /* A hole node which isn't multi-page should be garbage-collected
94730554d9SArtem B. Bityutskiy and merged anyway, so we just check for the frag size here,
95730554d9SArtem B. Bityutskiy rather than mucking around with actually reading the node
96730554d9SArtem B. Bityutskiy and checking the compression type, which is the real way
97730554d9SArtem B. Bityutskiy to tell a hole node. */
98*09cbfeafSKirill A. Shutemov if (frag->ofs & (PAGE_SIZE-1) && frag_prev(frag)
99*09cbfeafSKirill A. Shutemov && frag_prev(frag)->size < PAGE_SIZE && frag_prev(frag)->node) {
10081e39cf0SArtem B. Bityutskiy JFFS2_ERROR("REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2.\n",
10181e39cf0SArtem B. Bityutskiy ref_offset(fn->raw));
102730554d9SArtem B. Bityutskiy bitched = 1;
103730554d9SArtem B. Bityutskiy }
104730554d9SArtem B. Bityutskiy
105*09cbfeafSKirill A. Shutemov if ((frag->ofs+frag->size) & (PAGE_SIZE-1) && frag_next(frag)
106*09cbfeafSKirill A. Shutemov && frag_next(frag)->size < PAGE_SIZE && frag_next(frag)->node) {
10781e39cf0SArtem B. Bityutskiy JFFS2_ERROR("REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2.\n",
108730554d9SArtem B. Bityutskiy ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size);
109730554d9SArtem B. Bityutskiy bitched = 1;
110730554d9SArtem B. Bityutskiy }
111730554d9SArtem B. Bityutskiy }
112730554d9SArtem B. Bityutskiy }
113730554d9SArtem B. Bityutskiy
114730554d9SArtem B. Bityutskiy if (bitched) {
115e0c8e42fSArtem B. Bityutskiy JFFS2_ERROR("fragtree is corrupted.\n");
116e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_fragtree_nolock(f);
117730554d9SArtem B. Bityutskiy BUG();
118730554d9SArtem B. Bityutskiy }
119730554d9SArtem B. Bityutskiy }
120730554d9SArtem B. Bityutskiy
121730554d9SArtem B. Bityutskiy /*
122730554d9SArtem B. Bityutskiy * Check if the flash contains all 0xFF before we start writing.
123730554d9SArtem B. Bityutskiy */
124730554d9SArtem B. Bityutskiy void
__jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info * c,uint32_t ofs,int len)125e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
126e0c8e42fSArtem B. Bityutskiy uint32_t ofs, int len)
127730554d9SArtem B. Bityutskiy {
128730554d9SArtem B. Bityutskiy size_t retlen;
129730554d9SArtem B. Bityutskiy int ret, i;
130730554d9SArtem B. Bityutskiy unsigned char *buf;
131730554d9SArtem B. Bityutskiy
132730554d9SArtem B. Bityutskiy buf = kmalloc(len, GFP_KERNEL);
133730554d9SArtem B. Bityutskiy if (!buf)
134730554d9SArtem B. Bityutskiy return;
135730554d9SArtem B. Bityutskiy
136730554d9SArtem B. Bityutskiy ret = jffs2_flash_read(c, ofs, len, &retlen, buf);
137730554d9SArtem B. Bityutskiy if (ret || (retlen != len)) {
138e0c8e42fSArtem B. Bityutskiy JFFS2_WARNING("read %d bytes failed or short. ret %d, retlen %zd.\n",
139e0c8e42fSArtem B. Bityutskiy len, ret, retlen);
140730554d9SArtem B. Bityutskiy kfree(buf);
141730554d9SArtem B. Bityutskiy return;
142730554d9SArtem B. Bityutskiy }
143730554d9SArtem B. Bityutskiy
144730554d9SArtem B. Bityutskiy ret = 0;
145730554d9SArtem B. Bityutskiy for (i = 0; i < len; i++)
146730554d9SArtem B. Bityutskiy if (buf[i] != 0xff)
147730554d9SArtem B. Bityutskiy ret = 1;
148730554d9SArtem B. Bityutskiy
149730554d9SArtem B. Bityutskiy if (ret) {
15081e39cf0SArtem B. Bityutskiy 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",
15181e39cf0SArtem B. Bityutskiy ofs, ofs + i);
152e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_buffer(buf, len, ofs);
153730554d9SArtem B. Bityutskiy kfree(buf);
154730554d9SArtem B. Bityutskiy BUG();
155730554d9SArtem B. Bityutskiy }
156730554d9SArtem B. Bityutskiy
157730554d9SArtem B. Bityutskiy kfree(buf);
158730554d9SArtem B. Bityutskiy }
159730554d9SArtem B. Bityutskiy
__jffs2_dbg_superblock_counts(struct jffs2_sb_info * c)16085a62db6SDavid Woodhouse void __jffs2_dbg_superblock_counts(struct jffs2_sb_info *c)
16185a62db6SDavid Woodhouse {
16285a62db6SDavid Woodhouse struct jffs2_eraseblock *jeb;
16385a62db6SDavid Woodhouse uint32_t free = 0, dirty = 0, used = 0, wasted = 0,
16485a62db6SDavid Woodhouse erasing = 0, bad = 0, unchecked = 0;
16585a62db6SDavid Woodhouse int nr_counted = 0;
16685a62db6SDavid Woodhouse int dump = 0;
16785a62db6SDavid Woodhouse
16885a62db6SDavid Woodhouse if (c->gcblock) {
16985a62db6SDavid Woodhouse nr_counted++;
17085a62db6SDavid Woodhouse free += c->gcblock->free_size;
17185a62db6SDavid Woodhouse dirty += c->gcblock->dirty_size;
17285a62db6SDavid Woodhouse used += c->gcblock->used_size;
17385a62db6SDavid Woodhouse wasted += c->gcblock->wasted_size;
17485a62db6SDavid Woodhouse unchecked += c->gcblock->unchecked_size;
17585a62db6SDavid Woodhouse }
17685a62db6SDavid Woodhouse if (c->nextblock) {
17785a62db6SDavid Woodhouse nr_counted++;
17885a62db6SDavid Woodhouse free += c->nextblock->free_size;
17985a62db6SDavid Woodhouse dirty += c->nextblock->dirty_size;
18085a62db6SDavid Woodhouse used += c->nextblock->used_size;
18185a62db6SDavid Woodhouse wasted += c->nextblock->wasted_size;
18285a62db6SDavid Woodhouse unchecked += c->nextblock->unchecked_size;
18385a62db6SDavid Woodhouse }
18485a62db6SDavid Woodhouse list_for_each_entry(jeb, &c->clean_list, list) {
18585a62db6SDavid Woodhouse nr_counted++;
18685a62db6SDavid Woodhouse free += jeb->free_size;
18785a62db6SDavid Woodhouse dirty += jeb->dirty_size;
18885a62db6SDavid Woodhouse used += jeb->used_size;
18985a62db6SDavid Woodhouse wasted += jeb->wasted_size;
19085a62db6SDavid Woodhouse unchecked += jeb->unchecked_size;
19185a62db6SDavid Woodhouse }
19285a62db6SDavid Woodhouse list_for_each_entry(jeb, &c->very_dirty_list, list) {
19385a62db6SDavid Woodhouse nr_counted++;
19485a62db6SDavid Woodhouse free += jeb->free_size;
19585a62db6SDavid Woodhouse dirty += jeb->dirty_size;
19685a62db6SDavid Woodhouse used += jeb->used_size;
19785a62db6SDavid Woodhouse wasted += jeb->wasted_size;
19885a62db6SDavid Woodhouse unchecked += jeb->unchecked_size;
19985a62db6SDavid Woodhouse }
20085a62db6SDavid Woodhouse list_for_each_entry(jeb, &c->dirty_list, list) {
20185a62db6SDavid Woodhouse nr_counted++;
20285a62db6SDavid Woodhouse free += jeb->free_size;
20385a62db6SDavid Woodhouse dirty += jeb->dirty_size;
20485a62db6SDavid Woodhouse used += jeb->used_size;
20585a62db6SDavid Woodhouse wasted += jeb->wasted_size;
20685a62db6SDavid Woodhouse unchecked += jeb->unchecked_size;
20785a62db6SDavid Woodhouse }
20885a62db6SDavid Woodhouse list_for_each_entry(jeb, &c->erasable_list, list) {
20985a62db6SDavid Woodhouse nr_counted++;
21085a62db6SDavid Woodhouse free += jeb->free_size;
21185a62db6SDavid Woodhouse dirty += jeb->dirty_size;
21285a62db6SDavid Woodhouse used += jeb->used_size;
21385a62db6SDavid Woodhouse wasted += jeb->wasted_size;
21485a62db6SDavid Woodhouse unchecked += jeb->unchecked_size;
21585a62db6SDavid Woodhouse }
21685a62db6SDavid Woodhouse list_for_each_entry(jeb, &c->erasable_pending_wbuf_list, list) {
21785a62db6SDavid Woodhouse nr_counted++;
21885a62db6SDavid Woodhouse free += jeb->free_size;
21985a62db6SDavid Woodhouse dirty += jeb->dirty_size;
22085a62db6SDavid Woodhouse used += jeb->used_size;
22185a62db6SDavid Woodhouse wasted += jeb->wasted_size;
22285a62db6SDavid Woodhouse unchecked += jeb->unchecked_size;
22385a62db6SDavid Woodhouse }
22485a62db6SDavid Woodhouse list_for_each_entry(jeb, &c->erase_pending_list, list) {
22585a62db6SDavid Woodhouse nr_counted++;
22685a62db6SDavid Woodhouse free += jeb->free_size;
22785a62db6SDavid Woodhouse dirty += jeb->dirty_size;
22885a62db6SDavid Woodhouse used += jeb->used_size;
22985a62db6SDavid Woodhouse wasted += jeb->wasted_size;
23085a62db6SDavid Woodhouse unchecked += jeb->unchecked_size;
23185a62db6SDavid Woodhouse }
23285a62db6SDavid Woodhouse list_for_each_entry(jeb, &c->free_list, list) {
23385a62db6SDavid Woodhouse nr_counted++;
23485a62db6SDavid Woodhouse free += jeb->free_size;
23585a62db6SDavid Woodhouse dirty += jeb->dirty_size;
23685a62db6SDavid Woodhouse used += jeb->used_size;
23785a62db6SDavid Woodhouse wasted += jeb->wasted_size;
23885a62db6SDavid Woodhouse unchecked += jeb->unchecked_size;
23985a62db6SDavid Woodhouse }
24085a62db6SDavid Woodhouse list_for_each_entry(jeb, &c->bad_used_list, list) {
24185a62db6SDavid Woodhouse nr_counted++;
24285a62db6SDavid Woodhouse free += jeb->free_size;
24385a62db6SDavid Woodhouse dirty += jeb->dirty_size;
24485a62db6SDavid Woodhouse used += jeb->used_size;
24585a62db6SDavid Woodhouse wasted += jeb->wasted_size;
24685a62db6SDavid Woodhouse unchecked += jeb->unchecked_size;
24785a62db6SDavid Woodhouse }
24885a62db6SDavid Woodhouse
24985a62db6SDavid Woodhouse list_for_each_entry(jeb, &c->erasing_list, list) {
25085a62db6SDavid Woodhouse nr_counted++;
25185a62db6SDavid Woodhouse erasing += c->sector_size;
25285a62db6SDavid Woodhouse }
253e2bc322bSDavid Woodhouse list_for_each_entry(jeb, &c->erase_checking_list, list) {
254e2bc322bSDavid Woodhouse nr_counted++;
255e2bc322bSDavid Woodhouse erasing += c->sector_size;
256e2bc322bSDavid Woodhouse }
25785a62db6SDavid Woodhouse list_for_each_entry(jeb, &c->erase_complete_list, list) {
25885a62db6SDavid Woodhouse nr_counted++;
25985a62db6SDavid Woodhouse erasing += c->sector_size;
26085a62db6SDavid Woodhouse }
26185a62db6SDavid Woodhouse list_for_each_entry(jeb, &c->bad_list, list) {
26285a62db6SDavid Woodhouse nr_counted++;
26385a62db6SDavid Woodhouse bad += c->sector_size;
26485a62db6SDavid Woodhouse }
26585a62db6SDavid Woodhouse
26685a62db6SDavid Woodhouse #define check(sz) \
267da320f05SJoe Perches do { \
26885a62db6SDavid Woodhouse if (sz != c->sz##_size) { \
269da320f05SJoe Perches pr_warn("%s_size mismatch counted 0x%x, c->%s_size 0x%x\n", \
2709bbf29e4SJoe Perches #sz, sz, #sz, c->sz##_size); \
27185a62db6SDavid Woodhouse dump = 1; \
272da320f05SJoe Perches } \
273da320f05SJoe Perches } while (0)
274da320f05SJoe Perches
27585a62db6SDavid Woodhouse check(free);
27685a62db6SDavid Woodhouse check(dirty);
27785a62db6SDavid Woodhouse check(used);
27885a62db6SDavid Woodhouse check(wasted);
27985a62db6SDavid Woodhouse check(unchecked);
28085a62db6SDavid Woodhouse check(bad);
28185a62db6SDavid Woodhouse check(erasing);
282da320f05SJoe Perches
28385a62db6SDavid Woodhouse #undef check
28485a62db6SDavid Woodhouse
28585a62db6SDavid Woodhouse if (nr_counted != c->nr_blocks) {
286da320f05SJoe Perches pr_warn("%s counted only 0x%x blocks of 0x%x. Where are the others?\n",
28785a62db6SDavid Woodhouse __func__, nr_counted, c->nr_blocks);
28885a62db6SDavid Woodhouse dump = 1;
28985a62db6SDavid Woodhouse }
29085a62db6SDavid Woodhouse
29185a62db6SDavid Woodhouse if (dump) {
29285a62db6SDavid Woodhouse __jffs2_dbg_dump_block_lists_nolock(c);
29385a62db6SDavid Woodhouse BUG();
29485a62db6SDavid Woodhouse }
29585a62db6SDavid Woodhouse }
29685a62db6SDavid Woodhouse
297730554d9SArtem B. Bityutskiy /*
298730554d9SArtem B. Bityutskiy * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
299730554d9SArtem B. Bityutskiy */
300730554d9SArtem B. Bityutskiy void
__jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info * c,struct jffs2_eraseblock * jeb)301e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c,
302e0c8e42fSArtem B. Bityutskiy struct jffs2_eraseblock *jeb)
303e0c8e42fSArtem B. Bityutskiy {
304e0c8e42fSArtem B. Bityutskiy spin_lock(&c->erase_completion_lock);
305e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
306e0c8e42fSArtem B. Bityutskiy spin_unlock(&c->erase_completion_lock);
307e0c8e42fSArtem B. Bityutskiy }
308e0c8e42fSArtem B. Bityutskiy
309e0c8e42fSArtem B. Bityutskiy void
__jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info * c,struct jffs2_eraseblock * jeb)310e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
311e0c8e42fSArtem B. Bityutskiy struct jffs2_eraseblock *jeb)
312730554d9SArtem B. Bityutskiy {
313730554d9SArtem B. Bityutskiy uint32_t my_used_size = 0;
314730554d9SArtem B. Bityutskiy uint32_t my_unchecked_size = 0;
315730554d9SArtem B. Bityutskiy uint32_t my_dirty_size = 0;
316730554d9SArtem B. Bityutskiy struct jffs2_raw_node_ref *ref2 = jeb->first_node;
317730554d9SArtem B. Bityutskiy
318730554d9SArtem B. Bityutskiy while (ref2) {
319730554d9SArtem B. Bityutskiy uint32_t totlen = ref_totlen(c, jeb, ref2);
320730554d9SArtem B. Bityutskiy
321abb536e7SKyungmin Park if (ref_offset(ref2) < jeb->offset ||
322abb536e7SKyungmin Park ref_offset(ref2) > jeb->offset + c->sector_size) {
323e0c8e42fSArtem B. Bityutskiy JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.\n",
324730554d9SArtem B. Bityutskiy ref_offset(ref2), jeb->offset);
325e0c8e42fSArtem B. Bityutskiy goto error;
326730554d9SArtem B. Bityutskiy
327730554d9SArtem B. Bityutskiy }
328730554d9SArtem B. Bityutskiy if (ref_flags(ref2) == REF_UNCHECKED)
329730554d9SArtem B. Bityutskiy my_unchecked_size += totlen;
330730554d9SArtem B. Bityutskiy else if (!ref_obsolete(ref2))
331730554d9SArtem B. Bityutskiy my_used_size += totlen;
332730554d9SArtem B. Bityutskiy else
333730554d9SArtem B. Bityutskiy my_dirty_size += totlen;
334730554d9SArtem B. Bityutskiy
33599988f7bSDavid Woodhouse if ((!ref_next(ref2)) != (ref2 == jeb->last_node)) {
33699988f7bSDavid Woodhouse JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next at %#08x (mem %p), last_node is at %#08x (mem %p).\n",
33799988f7bSDavid Woodhouse ref_offset(ref2), ref2, ref_offset(ref_next(ref2)), ref_next(ref2),
338730554d9SArtem B. Bityutskiy ref_offset(jeb->last_node), jeb->last_node);
339e0c8e42fSArtem B. Bityutskiy goto error;
340730554d9SArtem B. Bityutskiy }
34199988f7bSDavid Woodhouse ref2 = ref_next(ref2);
342730554d9SArtem B. Bityutskiy }
343730554d9SArtem B. Bityutskiy
344730554d9SArtem B. Bityutskiy if (my_used_size != jeb->used_size) {
345e0c8e42fSArtem B. Bityutskiy JFFS2_ERROR("Calculated used size %#08x != stored used size %#08x.\n",
346730554d9SArtem B. Bityutskiy my_used_size, jeb->used_size);
347e0c8e42fSArtem B. Bityutskiy goto error;
348730554d9SArtem B. Bityutskiy }
349730554d9SArtem B. Bityutskiy
350730554d9SArtem B. Bityutskiy if (my_unchecked_size != jeb->unchecked_size) {
351e0c8e42fSArtem B. Bityutskiy JFFS2_ERROR("Calculated unchecked size %#08x != stored unchecked size %#08x.\n",
352730554d9SArtem B. Bityutskiy my_unchecked_size, jeb->unchecked_size);
353e0c8e42fSArtem B. Bityutskiy goto error;
354730554d9SArtem B. Bityutskiy }
355730554d9SArtem B. Bityutskiy
356e0c8e42fSArtem B. Bityutskiy #if 0
357e0c8e42fSArtem B. Bityutskiy /* This should work when we implement ref->__totlen elemination */
358730554d9SArtem B. Bityutskiy if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) {
359e0c8e42fSArtem B. Bityutskiy JFFS2_ERROR("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n",
360730554d9SArtem B. Bityutskiy my_dirty_size, jeb->dirty_size + jeb->wasted_size);
361e0c8e42fSArtem B. Bityutskiy goto error;
362730554d9SArtem B. Bityutskiy }
363730554d9SArtem B. Bityutskiy
364730554d9SArtem B. Bityutskiy if (jeb->free_size == 0
365730554d9SArtem B. Bityutskiy && my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) {
366e0c8e42fSArtem B. Bityutskiy JFFS2_ERROR("The sum of all nodes in block (%#x) != size of block (%#x)\n",
367730554d9SArtem B. Bityutskiy my_used_size + my_unchecked_size + my_dirty_size,
368730554d9SArtem B. Bityutskiy c->sector_size);
369e0c8e42fSArtem B. Bityutskiy goto error;
370730554d9SArtem B. Bityutskiy }
371e0c8e42fSArtem B. Bityutskiy #endif
372730554d9SArtem B. Bityutskiy
37385a62db6SDavid Woodhouse if (!(c->flags & (JFFS2_SB_FLAG_BUILDING|JFFS2_SB_FLAG_SCANNING)))
37485a62db6SDavid Woodhouse __jffs2_dbg_superblock_counts(c);
37585a62db6SDavid Woodhouse
376e0c8e42fSArtem B. Bityutskiy return;
377e0c8e42fSArtem B. Bityutskiy
378e0c8e42fSArtem B. Bityutskiy error:
379e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_node_refs_nolock(c, jeb);
380e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_jeb_nolock(jeb);
381e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_block_lists_nolock(c);
382e0c8e42fSArtem B. Bityutskiy BUG();
383e0c8e42fSArtem B. Bityutskiy
384e0c8e42fSArtem B. Bityutskiy }
385e0c8e42fSArtem B. Bityutskiy #endif /* JFFS2_DBG_PARANOIA_CHECKS */
386e0c8e42fSArtem B. Bityutskiy
387e0c8e42fSArtem B. Bityutskiy #if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS)
388730554d9SArtem B. Bityutskiy /*
389730554d9SArtem B. Bityutskiy * Dump the node_refs of the 'jeb' JFFS2 eraseblock.
390730554d9SArtem B. Bityutskiy */
391730554d9SArtem B. Bityutskiy void
__jffs2_dbg_dump_node_refs(struct jffs2_sb_info * c,struct jffs2_eraseblock * jeb)392e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c,
393e0c8e42fSArtem B. Bityutskiy struct jffs2_eraseblock *jeb)
394e0c8e42fSArtem B. Bityutskiy {
395e0c8e42fSArtem B. Bityutskiy spin_lock(&c->erase_completion_lock);
396e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_node_refs_nolock(c, jeb);
397e0c8e42fSArtem B. Bityutskiy spin_unlock(&c->erase_completion_lock);
398e0c8e42fSArtem B. Bityutskiy }
399e0c8e42fSArtem B. Bityutskiy
400e0c8e42fSArtem B. Bityutskiy void
__jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info * c,struct jffs2_eraseblock * jeb)401e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c,
402e0c8e42fSArtem B. Bityutskiy struct jffs2_eraseblock *jeb)
403730554d9SArtem B. Bityutskiy {
404730554d9SArtem B. Bityutskiy struct jffs2_raw_node_ref *ref;
405730554d9SArtem B. Bityutskiy int i = 0;
406730554d9SArtem B. Bityutskiy
40781e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG_MSG_PREFIX " Dump node_refs of the eraseblock %#08x\n", jeb->offset);
408730554d9SArtem B. Bityutskiy if (!jeb->first_node) {
40981e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG_MSG_PREFIX " no nodes in the eraseblock %#08x\n", jeb->offset);
410730554d9SArtem B. Bityutskiy return;
411730554d9SArtem B. Bityutskiy }
412730554d9SArtem B. Bityutskiy
41381e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG);
41499988f7bSDavid Woodhouse for (ref = jeb->first_node; ; ref = ref_next(ref)) {
41527e6b8e3SDavid Woodhouse printk("%#08x", ref_offset(ref));
41627e6b8e3SDavid Woodhouse #ifdef TEST_TOTLEN
41727e6b8e3SDavid Woodhouse printk("(%x)", ref->__totlen);
41827e6b8e3SDavid Woodhouse #endif
41999988f7bSDavid Woodhouse if (ref_next(ref))
420730554d9SArtem B. Bityutskiy printk("->");
421730554d9SArtem B. Bityutskiy else
422730554d9SArtem B. Bityutskiy break;
423730554d9SArtem B. Bityutskiy if (++i == 4) {
424730554d9SArtem B. Bityutskiy i = 0;
42581e39cf0SArtem B. Bityutskiy printk("\n" JFFS2_DBG);
426730554d9SArtem B. Bityutskiy }
427730554d9SArtem B. Bityutskiy }
428730554d9SArtem B. Bityutskiy printk("\n");
429730554d9SArtem B. Bityutskiy }
430730554d9SArtem B. Bityutskiy
431e0c8e42fSArtem B. Bityutskiy /*
432e0c8e42fSArtem B. Bityutskiy * Dump an eraseblock's space accounting.
433e0c8e42fSArtem B. Bityutskiy */
434730554d9SArtem B. Bityutskiy void
__jffs2_dbg_dump_jeb(struct jffs2_sb_info * c,struct jffs2_eraseblock * jeb)435e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
436730554d9SArtem B. Bityutskiy {
437e0c8e42fSArtem B. Bityutskiy spin_lock(&c->erase_completion_lock);
438e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_jeb_nolock(jeb);
439e0c8e42fSArtem B. Bityutskiy spin_unlock(&c->erase_completion_lock);
440e0c8e42fSArtem B. Bityutskiy }
441e0c8e42fSArtem B. Bityutskiy
442e0c8e42fSArtem B. Bityutskiy void
__jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock * jeb)443e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb)
444e0c8e42fSArtem B. Bityutskiy {
445e0c8e42fSArtem B. Bityutskiy if (!jeb)
446e0c8e42fSArtem B. Bityutskiy return;
447e0c8e42fSArtem B. Bityutskiy
44881e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG_MSG_PREFIX " dump space accounting for the eraseblock at %#08x:\n",
449e0c8e42fSArtem B. Bityutskiy jeb->offset);
450e0c8e42fSArtem B. Bityutskiy
45181e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "used_size: %#08x\n", jeb->used_size);
45281e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "dirty_size: %#08x\n", jeb->dirty_size);
45381e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "wasted_size: %#08x\n", jeb->wasted_size);
45481e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "unchecked_size: %#08x\n", jeb->unchecked_size);
45581e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "free_size: %#08x\n", jeb->free_size);
456e0c8e42fSArtem B. Bityutskiy }
457e0c8e42fSArtem B. Bityutskiy
458e0c8e42fSArtem B. Bityutskiy void
__jffs2_dbg_dump_block_lists(struct jffs2_sb_info * c)459e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c)
460e0c8e42fSArtem B. Bityutskiy {
461e0c8e42fSArtem B. Bityutskiy spin_lock(&c->erase_completion_lock);
462e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_block_lists_nolock(c);
463e0c8e42fSArtem B. Bityutskiy spin_unlock(&c->erase_completion_lock);
464e0c8e42fSArtem B. Bityutskiy }
465e0c8e42fSArtem B. Bityutskiy
466e0c8e42fSArtem B. Bityutskiy void
__jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info * c)467e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c)
468e0c8e42fSArtem B. Bityutskiy {
46981e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG_MSG_PREFIX " dump JFFS2 blocks lists:\n");
470e0c8e42fSArtem B. Bityutskiy
47181e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "flash_size: %#08x\n", c->flash_size);
47281e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "used_size: %#08x\n", c->used_size);
47381e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "dirty_size: %#08x\n", c->dirty_size);
47481e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "wasted_size: %#08x\n", c->wasted_size);
47581e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "unchecked_size: %#08x\n", c->unchecked_size);
47681e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "free_size: %#08x\n", c->free_size);
47781e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "erasing_size: %#08x\n", c->erasing_size);
47881e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "bad_size: %#08x\n", c->bad_size);
47981e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "sector_size: %#08x\n", c->sector_size);
48081e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "jffs2_reserved_blocks size: %#08x\n",
481730554d9SArtem B. Bityutskiy c->sector_size * c->resv_blocks_write);
482730554d9SArtem B. Bityutskiy
483730554d9SArtem B. Bityutskiy if (c->nextblock)
48481e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
485730554d9SArtem B. Bityutskiy c->nextblock->offset, c->nextblock->used_size,
486730554d9SArtem B. Bityutskiy c->nextblock->dirty_size, c->nextblock->wasted_size,
487730554d9SArtem B. Bityutskiy c->nextblock->unchecked_size, c->nextblock->free_size);
488730554d9SArtem B. Bityutskiy else
48981e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "nextblock: NULL\n");
490730554d9SArtem B. Bityutskiy
491730554d9SArtem B. Bityutskiy if (c->gcblock)
49281e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
493730554d9SArtem B. Bityutskiy c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size,
494730554d9SArtem B. Bityutskiy c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
495730554d9SArtem B. Bityutskiy else
49681e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "gcblock: NULL\n");
497730554d9SArtem B. Bityutskiy
498730554d9SArtem B. Bityutskiy if (list_empty(&c->clean_list)) {
49981e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "clean_list: empty\n");
500730554d9SArtem B. Bityutskiy } else {
501730554d9SArtem B. Bityutskiy struct list_head *this;
502730554d9SArtem B. Bityutskiy int numblocks = 0;
503730554d9SArtem B. Bityutskiy uint32_t dirty = 0;
504730554d9SArtem B. Bityutskiy
505730554d9SArtem B. Bityutskiy list_for_each(this, &c->clean_list) {
506730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
507730554d9SArtem B. Bityutskiy numblocks ++;
508730554d9SArtem B. Bityutskiy dirty += jeb->wasted_size;
509730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
51081e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
511730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
512730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size);
513730554d9SArtem B. Bityutskiy }
514730554d9SArtem B. Bityutskiy }
515730554d9SArtem B. Bityutskiy
51681e39cf0SArtem B. Bityutskiy printk (JFFS2_DBG "Contains %d blocks with total wasted size %u, average wasted size: %u\n",
517730554d9SArtem B. Bityutskiy numblocks, dirty, dirty / numblocks);
518730554d9SArtem B. Bityutskiy }
519730554d9SArtem B. Bityutskiy
520730554d9SArtem B. Bityutskiy if (list_empty(&c->very_dirty_list)) {
52181e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "very_dirty_list: empty\n");
522730554d9SArtem B. Bityutskiy } else {
523730554d9SArtem B. Bityutskiy struct list_head *this;
524730554d9SArtem B. Bityutskiy int numblocks = 0;
525730554d9SArtem B. Bityutskiy uint32_t dirty = 0;
526730554d9SArtem B. Bityutskiy
527730554d9SArtem B. Bityutskiy list_for_each(this, &c->very_dirty_list) {
528730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
529730554d9SArtem B. Bityutskiy
530730554d9SArtem B. Bityutskiy numblocks ++;
531730554d9SArtem B. Bityutskiy dirty += jeb->dirty_size;
532730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
53381e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
534730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
535730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size);
536730554d9SArtem B. Bityutskiy }
537730554d9SArtem B. Bityutskiy }
538730554d9SArtem B. Bityutskiy
53981e39cf0SArtem B. Bityutskiy printk (JFFS2_DBG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
540730554d9SArtem B. Bityutskiy numblocks, dirty, dirty / numblocks);
541730554d9SArtem B. Bityutskiy }
542730554d9SArtem B. Bityutskiy
543730554d9SArtem B. Bityutskiy if (list_empty(&c->dirty_list)) {
54481e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "dirty_list: empty\n");
545730554d9SArtem B. Bityutskiy } else {
546730554d9SArtem B. Bityutskiy struct list_head *this;
547730554d9SArtem B. Bityutskiy int numblocks = 0;
548730554d9SArtem B. Bityutskiy uint32_t dirty = 0;
549730554d9SArtem B. Bityutskiy
550730554d9SArtem B. Bityutskiy list_for_each(this, &c->dirty_list) {
551730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
552730554d9SArtem B. Bityutskiy
553730554d9SArtem B. Bityutskiy numblocks ++;
554730554d9SArtem B. Bityutskiy dirty += jeb->dirty_size;
555730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
55681e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
557730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
558730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size);
559730554d9SArtem B. Bityutskiy }
560730554d9SArtem B. Bityutskiy }
561730554d9SArtem B. Bityutskiy
56281e39cf0SArtem B. Bityutskiy printk (JFFS2_DBG "contains %d blocks with total dirty size %u, average dirty size: %u\n",
563730554d9SArtem B. Bityutskiy numblocks, dirty, dirty / numblocks);
564730554d9SArtem B. Bityutskiy }
565730554d9SArtem B. Bityutskiy
566730554d9SArtem B. Bityutskiy if (list_empty(&c->erasable_list)) {
56781e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "erasable_list: empty\n");
568730554d9SArtem B. Bityutskiy } else {
569730554d9SArtem B. Bityutskiy struct list_head *this;
570730554d9SArtem B. Bityutskiy
571730554d9SArtem B. Bityutskiy list_for_each(this, &c->erasable_list) {
572730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
573730554d9SArtem B. Bityutskiy
574730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
57581e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
576730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
577730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size);
578730554d9SArtem B. Bityutskiy }
579730554d9SArtem B. Bityutskiy }
580730554d9SArtem B. Bityutskiy }
581730554d9SArtem B. Bityutskiy
582730554d9SArtem B. Bityutskiy if (list_empty(&c->erasing_list)) {
58381e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "erasing_list: empty\n");
584730554d9SArtem B. Bityutskiy } else {
585730554d9SArtem B. Bityutskiy struct list_head *this;
586730554d9SArtem B. Bityutskiy
587730554d9SArtem B. Bityutskiy list_for_each(this, &c->erasing_list) {
588730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
589730554d9SArtem B. Bityutskiy
590730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
59181e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
592730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
593730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size);
594730554d9SArtem B. Bityutskiy }
595730554d9SArtem B. Bityutskiy }
596730554d9SArtem B. Bityutskiy }
597e2bc322bSDavid Woodhouse if (list_empty(&c->erase_checking_list)) {
598e2bc322bSDavid Woodhouse printk(JFFS2_DBG "erase_checking_list: empty\n");
599e2bc322bSDavid Woodhouse } else {
600e2bc322bSDavid Woodhouse struct list_head *this;
601e2bc322bSDavid Woodhouse
602e2bc322bSDavid Woodhouse list_for_each(this, &c->erase_checking_list) {
603e2bc322bSDavid Woodhouse struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
604e2bc322bSDavid Woodhouse
605e2bc322bSDavid Woodhouse if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
606e2bc322bSDavid Woodhouse printk(JFFS2_DBG "erase_checking_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
607e2bc322bSDavid Woodhouse jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
608e2bc322bSDavid Woodhouse jeb->unchecked_size, jeb->free_size);
609e2bc322bSDavid Woodhouse }
610e2bc322bSDavid Woodhouse }
611e2bc322bSDavid Woodhouse }
612730554d9SArtem B. Bityutskiy
613730554d9SArtem B. Bityutskiy if (list_empty(&c->erase_pending_list)) {
61481e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "erase_pending_list: empty\n");
615730554d9SArtem B. Bityutskiy } else {
616730554d9SArtem B. Bityutskiy struct list_head *this;
617730554d9SArtem B. Bityutskiy
618730554d9SArtem B. Bityutskiy list_for_each(this, &c->erase_pending_list) {
619730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
620730554d9SArtem B. Bityutskiy
621730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
62281e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
623730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
624730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size);
625730554d9SArtem B. Bityutskiy }
626730554d9SArtem B. Bityutskiy }
627730554d9SArtem B. Bityutskiy }
628730554d9SArtem B. Bityutskiy
629730554d9SArtem B. Bityutskiy if (list_empty(&c->erasable_pending_wbuf_list)) {
63081e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "erasable_pending_wbuf_list: empty\n");
631730554d9SArtem B. Bityutskiy } else {
632730554d9SArtem B. Bityutskiy struct list_head *this;
633730554d9SArtem B. Bityutskiy
634730554d9SArtem B. Bityutskiy list_for_each(this, &c->erasable_pending_wbuf_list) {
635730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
636730554d9SArtem B. Bityutskiy
637730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
63881e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
639730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
640730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size);
641730554d9SArtem B. Bityutskiy }
642730554d9SArtem B. Bityutskiy }
643730554d9SArtem B. Bityutskiy }
644730554d9SArtem B. Bityutskiy
645730554d9SArtem B. Bityutskiy if (list_empty(&c->free_list)) {
64681e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "free_list: empty\n");
647730554d9SArtem B. Bityutskiy } else {
648730554d9SArtem B. Bityutskiy struct list_head *this;
649730554d9SArtem B. Bityutskiy
650730554d9SArtem B. Bityutskiy list_for_each(this, &c->free_list) {
651730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
652730554d9SArtem B. Bityutskiy
653730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
65481e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
655730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
656730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size);
657730554d9SArtem B. Bityutskiy }
658730554d9SArtem B. Bityutskiy }
659730554d9SArtem B. Bityutskiy }
660730554d9SArtem B. Bityutskiy
661730554d9SArtem B. Bityutskiy if (list_empty(&c->bad_list)) {
66281e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "bad_list: empty\n");
663730554d9SArtem B. Bityutskiy } else {
664730554d9SArtem B. Bityutskiy struct list_head *this;
665730554d9SArtem B. Bityutskiy
666730554d9SArtem B. Bityutskiy list_for_each(this, &c->bad_list) {
667730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
668730554d9SArtem B. Bityutskiy
669730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
67081e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
671730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
672730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size);
673730554d9SArtem B. Bityutskiy }
674730554d9SArtem B. Bityutskiy }
675730554d9SArtem B. Bityutskiy }
676730554d9SArtem B. Bityutskiy
677730554d9SArtem B. Bityutskiy if (list_empty(&c->bad_used_list)) {
67881e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "bad_used_list: empty\n");
679730554d9SArtem B. Bityutskiy } else {
680730554d9SArtem B. Bityutskiy struct list_head *this;
681730554d9SArtem B. Bityutskiy
682730554d9SArtem B. Bityutskiy list_for_each(this, &c->bad_used_list) {
683730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
684730554d9SArtem B. Bityutskiy
685730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) {
68681e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n",
687730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size,
688730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size);
689730554d9SArtem B. Bityutskiy }
690730554d9SArtem B. Bityutskiy }
691730554d9SArtem B. Bityutskiy }
692730554d9SArtem B. Bityutskiy }
693730554d9SArtem B. Bityutskiy
694730554d9SArtem B. Bityutskiy void
__jffs2_dbg_dump_fragtree(struct jffs2_inode_info * f)695e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f)
696e0c8e42fSArtem B. Bityutskiy {
697ced22070SDavid Woodhouse mutex_lock(&f->sem);
698e0c8e42fSArtem B. Bityutskiy jffs2_dbg_dump_fragtree_nolock(f);
699ced22070SDavid Woodhouse mutex_unlock(&f->sem);
700e0c8e42fSArtem B. Bityutskiy }
701e0c8e42fSArtem B. Bityutskiy
702e0c8e42fSArtem B. Bityutskiy void
__jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info * f)703e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f)
704730554d9SArtem B. Bityutskiy {
705730554d9SArtem B. Bityutskiy struct jffs2_node_frag *this = frag_first(&f->fragtree);
706730554d9SArtem B. Bityutskiy uint32_t lastofs = 0;
707730554d9SArtem B. Bityutskiy int buggy = 0;
708730554d9SArtem B. Bityutskiy
70981e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG_MSG_PREFIX " dump fragtree of ino #%u\n", f->inocache->ino);
710730554d9SArtem B. Bityutskiy while(this) {
711730554d9SArtem B. Bityutskiy if (this->node)
71281e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "frag %#04x-%#04x: %#08x(%d) on flash (*%p), left (%p), right (%p), parent (%p)\n",
713730554d9SArtem B. Bityutskiy this->ofs, this->ofs+this->size, ref_offset(this->node->raw),
714730554d9SArtem B. Bityutskiy ref_flags(this->node->raw), this, frag_left(this), frag_right(this),
715730554d9SArtem B. Bityutskiy frag_parent(this));
716730554d9SArtem B. Bityutskiy else
71781e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n",
718730554d9SArtem B. Bityutskiy this->ofs, this->ofs+this->size, this, frag_left(this),
719730554d9SArtem B. Bityutskiy frag_right(this), frag_parent(this));
720730554d9SArtem B. Bityutskiy if (this->ofs != lastofs)
721730554d9SArtem B. Bityutskiy buggy = 1;
722730554d9SArtem B. Bityutskiy lastofs = this->ofs + this->size;
723730554d9SArtem B. Bityutskiy this = frag_next(this);
724730554d9SArtem B. Bityutskiy }
725730554d9SArtem B. Bityutskiy
726730554d9SArtem B. Bityutskiy if (f->metadata)
72781e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
728730554d9SArtem B. Bityutskiy
729730554d9SArtem B. Bityutskiy if (buggy) {
730e0c8e42fSArtem B. Bityutskiy JFFS2_ERROR("frag tree got a hole in it.\n");
731730554d9SArtem B. Bityutskiy BUG();
732730554d9SArtem B. Bityutskiy }
733730554d9SArtem B. Bityutskiy }
734730554d9SArtem B. Bityutskiy
735e0c8e42fSArtem B. Bityutskiy #define JFFS2_BUFDUMP_BYTES_PER_LINE 32
736730554d9SArtem B. Bityutskiy void
__jffs2_dbg_dump_buffer(unsigned char * buf,int len,uint32_t offs)737e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs)
738730554d9SArtem B. Bityutskiy {
739e0c8e42fSArtem B. Bityutskiy int skip;
740e0c8e42fSArtem B. Bityutskiy int i;
741e0c8e42fSArtem B. Bityutskiy
74281e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG_MSG_PREFIX " dump from offset %#08x to offset %#08x (%x bytes).\n",
743e0c8e42fSArtem B. Bityutskiy offs, offs + len, len);
744e0c8e42fSArtem B. Bityutskiy i = skip = offs % JFFS2_BUFDUMP_BYTES_PER_LINE;
745e0c8e42fSArtem B. Bityutskiy offs = offs & ~(JFFS2_BUFDUMP_BYTES_PER_LINE - 1);
746e0c8e42fSArtem B. Bityutskiy
747e0c8e42fSArtem B. Bityutskiy if (skip != 0)
74881e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "%#08x: ", offs);
749e0c8e42fSArtem B. Bityutskiy
750e0c8e42fSArtem B. Bityutskiy while (skip--)
751e0c8e42fSArtem B. Bityutskiy printk(" ");
752730554d9SArtem B. Bityutskiy
753730554d9SArtem B. Bityutskiy while (i < len) {
754e0c8e42fSArtem B. Bityutskiy if ((i % JFFS2_BUFDUMP_BYTES_PER_LINE) == 0 && i != len -1) {
755e0c8e42fSArtem B. Bityutskiy if (i != 0)
756e0c8e42fSArtem B. Bityutskiy printk("\n");
757e0c8e42fSArtem B. Bityutskiy offs += JFFS2_BUFDUMP_BYTES_PER_LINE;
75881e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "%0#8x: ", offs);
759730554d9SArtem B. Bityutskiy }
760730554d9SArtem B. Bityutskiy
761e0c8e42fSArtem B. Bityutskiy printk("%02x ", buf[i]);
762e0c8e42fSArtem B. Bityutskiy
763e0c8e42fSArtem B. Bityutskiy i += 1;
764730554d9SArtem B. Bityutskiy }
765730554d9SArtem B. Bityutskiy
766e0c8e42fSArtem B. Bityutskiy printk("\n");
767e0c8e42fSArtem B. Bityutskiy }
768e0c8e42fSArtem B. Bityutskiy
769e0c8e42fSArtem B. Bityutskiy /*
770e0c8e42fSArtem B. Bityutskiy * Dump a JFFS2 node.
771e0c8e42fSArtem B. Bityutskiy */
772e0c8e42fSArtem B. Bityutskiy void
__jffs2_dbg_dump_node(struct jffs2_sb_info * c,uint32_t ofs)773e0c8e42fSArtem B. Bityutskiy __jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs)
774e0c8e42fSArtem B. Bityutskiy {
775e0c8e42fSArtem B. Bityutskiy union jffs2_node_union node;
776e0c8e42fSArtem B. Bityutskiy int len = sizeof(union jffs2_node_union);
777e0c8e42fSArtem B. Bityutskiy size_t retlen;
778e0c8e42fSArtem B. Bityutskiy uint32_t crc;
779e0c8e42fSArtem B. Bityutskiy int ret;
780e0c8e42fSArtem B. Bityutskiy
78181e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG_MSG_PREFIX " dump node at offset %#08x.\n", ofs);
782e0c8e42fSArtem B. Bityutskiy
783e0c8e42fSArtem B. Bityutskiy ret = jffs2_flash_read(c, ofs, len, &retlen, (unsigned char *)&node);
784e0c8e42fSArtem B. Bityutskiy if (ret || (retlen != len)) {
785e0c8e42fSArtem B. Bityutskiy JFFS2_ERROR("read %d bytes failed or short. ret %d, retlen %zd.\n",
786e0c8e42fSArtem B. Bityutskiy len, ret, retlen);
787e0c8e42fSArtem B. Bityutskiy return;
788e0c8e42fSArtem B. Bityutskiy }
789e0c8e42fSArtem B. Bityutskiy
79081e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "magic:\t%#04x\n", je16_to_cpu(node.u.magic));
79181e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "nodetype:\t%#04x\n", je16_to_cpu(node.u.nodetype));
79281e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "totlen:\t%#08x\n", je32_to_cpu(node.u.totlen));
79381e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "hdr_crc:\t%#08x\n", je32_to_cpu(node.u.hdr_crc));
794e0c8e42fSArtem B. Bityutskiy
795e0c8e42fSArtem B. Bityutskiy crc = crc32(0, &node.u, sizeof(node.u) - 4);
796e0c8e42fSArtem B. Bityutskiy if (crc != je32_to_cpu(node.u.hdr_crc)) {
797e0c8e42fSArtem B. Bityutskiy JFFS2_ERROR("wrong common header CRC.\n");
798e0c8e42fSArtem B. Bityutskiy return;
799e0c8e42fSArtem B. Bityutskiy }
800e0c8e42fSArtem B. Bityutskiy
801e0c8e42fSArtem B. Bityutskiy if (je16_to_cpu(node.u.magic) != JFFS2_MAGIC_BITMASK &&
802e0c8e42fSArtem B. Bityutskiy je16_to_cpu(node.u.magic) != JFFS2_OLD_MAGIC_BITMASK)
803e0c8e42fSArtem B. Bityutskiy {
804e0c8e42fSArtem B. Bityutskiy JFFS2_ERROR("wrong node magic: %#04x instead of %#04x.\n",
805e0c8e42fSArtem B. Bityutskiy je16_to_cpu(node.u.magic), JFFS2_MAGIC_BITMASK);
806e0c8e42fSArtem B. Bityutskiy return;
807e0c8e42fSArtem B. Bityutskiy }
808e0c8e42fSArtem B. Bityutskiy
809e0c8e42fSArtem B. Bityutskiy switch(je16_to_cpu(node.u.nodetype)) {
810e0c8e42fSArtem B. Bityutskiy
811e0c8e42fSArtem B. Bityutskiy case JFFS2_NODETYPE_INODE:
812e0c8e42fSArtem B. Bityutskiy
81381e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "the node is inode node\n");
81481e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.i.ino));
81581e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.i.version));
81681e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "mode:\t%#08x\n", node.i.mode.m);
81781e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "uid:\t%#04x\n", je16_to_cpu(node.i.uid));
81881e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "gid:\t%#04x\n", je16_to_cpu(node.i.gid));
81981e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "isize:\t%#08x\n", je32_to_cpu(node.i.isize));
82081e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "atime:\t%#08x\n", je32_to_cpu(node.i.atime));
82181e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "mtime:\t%#08x\n", je32_to_cpu(node.i.mtime));
82281e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "ctime:\t%#08x\n", je32_to_cpu(node.i.ctime));
82381e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "offset:\t%#08x\n", je32_to_cpu(node.i.offset));
82481e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "csize:\t%#08x\n", je32_to_cpu(node.i.csize));
82581e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "dsize:\t%#08x\n", je32_to_cpu(node.i.dsize));
82681e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "compr:\t%#02x\n", node.i.compr);
82781e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "usercompr:\t%#02x\n", node.i.usercompr);
82881e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "flags:\t%#04x\n", je16_to_cpu(node.i.flags));
82981e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "data_crc:\t%#08x\n", je32_to_cpu(node.i.data_crc));
83081e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.i.node_crc));
83181e39cf0SArtem B. Bityutskiy
832e0c8e42fSArtem B. Bityutskiy crc = crc32(0, &node.i, sizeof(node.i) - 8);
833e0c8e42fSArtem B. Bityutskiy if (crc != je32_to_cpu(node.i.node_crc)) {
834e0c8e42fSArtem B. Bityutskiy JFFS2_ERROR("wrong node header CRC.\n");
835e0c8e42fSArtem B. Bityutskiy return;
836e0c8e42fSArtem B. Bityutskiy }
837e0c8e42fSArtem B. Bityutskiy break;
838e0c8e42fSArtem B. Bityutskiy
839e0c8e42fSArtem B. Bityutskiy case JFFS2_NODETYPE_DIRENT:
840e0c8e42fSArtem B. Bityutskiy
84181e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "the node is dirent node\n");
84281e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "pino:\t%#08x\n", je32_to_cpu(node.d.pino));
84381e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.d.version));
84481e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.d.ino));
84581e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "mctime:\t%#08x\n", je32_to_cpu(node.d.mctime));
84681e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "nsize:\t%#02x\n", node.d.nsize);
84781e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "type:\t%#02x\n", node.d.type);
84881e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.d.node_crc));
84981e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "name_crc:\t%#08x\n", je32_to_cpu(node.d.name_crc));
850e0c8e42fSArtem B. Bityutskiy
851e0c8e42fSArtem B. Bityutskiy node.d.name[node.d.nsize] = '\0';
85281e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "name:\t\"%s\"\n", node.d.name);
853e0c8e42fSArtem B. Bityutskiy
854e0c8e42fSArtem B. Bityutskiy crc = crc32(0, &node.d, sizeof(node.d) - 8);
855e0c8e42fSArtem B. Bityutskiy if (crc != je32_to_cpu(node.d.node_crc)) {
856e0c8e42fSArtem B. Bityutskiy JFFS2_ERROR("wrong node header CRC.\n");
857e0c8e42fSArtem B. Bityutskiy return;
858e0c8e42fSArtem B. Bityutskiy }
859e0c8e42fSArtem B. Bityutskiy break;
860e0c8e42fSArtem B. Bityutskiy
861e0c8e42fSArtem B. Bityutskiy default:
86281e39cf0SArtem B. Bityutskiy printk(JFFS2_DBG "node type is unknown\n");
863e0c8e42fSArtem B. Bityutskiy break;
864730554d9SArtem B. Bityutskiy }
865730554d9SArtem B. Bityutskiy }
866e0c8e42fSArtem B. Bityutskiy #endif /* JFFS2_DBG_DUMPS || JFFS2_DBG_PARANOIA_CHECKS */
867