diff options
author | Artem B. Bityutskiy <dedekind@infradead.org> | 2005-07-17 02:56:26 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-11-06 10:21:25 -0500 |
commit | 730554d94607572ef8300c5c9848540b42394897 (patch) | |
tree | fcefe9225afae333e09a59bdb2b8ac6e44676ce6 /fs/jffs2/debug.c | |
parent | dae6227f71fedb40b2478d3062397d3ab54e7556 (diff) |
[JFFS2] Debug code clean up - step 1
Move debug functions into a seperate source file
Signed-off-by: Artem B. Bityutskiy <dedekind@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/jffs2/debug.c')
-rw-r--r-- | fs/jffs2/debug.c | 495 |
1 files changed, 495 insertions, 0 deletions
diff --git a/fs/jffs2/debug.c b/fs/jffs2/debug.c new file mode 100644 index 000000000000..9da524ca4e66 --- /dev/null +++ b/fs/jffs2/debug.c | |||
@@ -0,0 +1,495 @@ | |||
1 | /* | ||
2 | * JFFS2 -- Journalling Flash File System, Version 2. | ||
3 | * | ||
4 | * Copyright (C) 2001-2003 Red Hat, Inc. | ||
5 | * | ||
6 | * Created by David Woodhouse <dwmw2@infradead.org> | ||
7 | * | ||
8 | * For licensing information, see the file 'LICENCE' in this directory. | ||
9 | * | ||
10 | * $Id: debug.c,v 1.1 2005/07/17 06:56:20 dedekind Exp $ | ||
11 | * | ||
12 | */ | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/pagemap.h> | ||
15 | #include "nodelist.h" | ||
16 | #include "debug.h" | ||
17 | |||
18 | #ifdef JFFS2_DBG_PARANOIA_CHECKS | ||
19 | |||
20 | void | ||
21 | jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f) | ||
22 | { | ||
23 | struct jffs2_node_frag *frag; | ||
24 | int bitched = 0; | ||
25 | |||
26 | for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) { | ||
27 | struct jffs2_full_dnode *fn = frag->node; | ||
28 | |||
29 | if (!fn || !fn->raw) | ||
30 | continue; | ||
31 | |||
32 | if (ref_flags(fn->raw) == REF_PRISTINE) { | ||
33 | if (fn->frags > 1) { | ||
34 | printk(KERN_ERR "REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2\n", | ||
35 | ref_offset(fn->raw), fn->frags); | ||
36 | bitched = 1; | ||
37 | } | ||
38 | |||
39 | /* A hole node which isn't multi-page should be garbage-collected | ||
40 | and merged anyway, so we just check for the frag size here, | ||
41 | rather than mucking around with actually reading the node | ||
42 | and checking the compression type, which is the real way | ||
43 | to tell a hole node. */ | ||
44 | if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag) | ||
45 | && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) { | ||
46 | printk(KERN_ERR "REF_PRISTINE node at 0x%08x had a previous non-hole frag " | ||
47 | "in the same page. Tell dwmw2\n", ref_offset(fn->raw)); | ||
48 | bitched = 1; | ||
49 | } | ||
50 | |||
51 | if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag) | ||
52 | && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) { | ||
53 | printk(KERN_ERR "REF_PRISTINE node at 0x%08x (%08x-%08x) had a following " | ||
54 | "non-hole frag in the same page. Tell dwmw2\n", | ||
55 | ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size); | ||
56 | bitched = 1; | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | |||
61 | if (bitched) { | ||
62 | printk(KERN_ERR "Fragtree is corrupted. Fragtree dump:\n"); | ||
63 | jffs2_dbg_dump_fragtree(f); | ||
64 | BUG(); | ||
65 | } | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * Check if the flash contains all 0xFF before we start writing. | ||
70 | */ | ||
71 | void | ||
72 | jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c, uint32_t ofs, int len) | ||
73 | { | ||
74 | size_t retlen; | ||
75 | int ret, i; | ||
76 | unsigned char *buf; | ||
77 | |||
78 | buf = kmalloc(len, GFP_KERNEL); | ||
79 | if (!buf) | ||
80 | return; | ||
81 | |||
82 | ret = jffs2_flash_read(c, ofs, len, &retlen, buf); | ||
83 | if (ret || (retlen != len)) { | ||
84 | printk(KERN_WARNING "read %d bytes failed or short in %s(). ret %d, retlen %zd\n", | ||
85 | len, __FUNCTION__, ret, retlen); | ||
86 | kfree(buf); | ||
87 | return; | ||
88 | } | ||
89 | |||
90 | ret = 0; | ||
91 | for (i = 0; i < len; i++) | ||
92 | if (buf[i] != 0xff) | ||
93 | ret = 1; | ||
94 | |||
95 | if (ret) { | ||
96 | printk(KERN_ERR "ARGH. About to write node to %#08x on flash, but there are data " | ||
97 | "already there. The first corrupted byte is at %#08x.\n", ofs, ofs + i); | ||
98 | jffs2_dbg_dump_buffer(buf, len, ofs); | ||
99 | kfree(buf); | ||
100 | BUG(); | ||
101 | } | ||
102 | |||
103 | kfree(buf); | ||
104 | } | ||
105 | |||
106 | /* | ||
107 | * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'. | ||
108 | */ | ||
109 | void | ||
110 | jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) | ||
111 | { | ||
112 | uint32_t my_used_size = 0; | ||
113 | uint32_t my_unchecked_size = 0; | ||
114 | uint32_t my_dirty_size = 0; | ||
115 | struct jffs2_raw_node_ref *ref2 = jeb->first_node; | ||
116 | |||
117 | while (ref2) { | ||
118 | uint32_t totlen = ref_totlen(c, jeb, ref2); | ||
119 | |||
120 | if (ref2->flash_offset < jeb->offset || | ||
121 | ref2->flash_offset > jeb->offset + c->sector_size) { | ||
122 | printk(KERN_ERR "node_ref %#08x shouldn't be in block at %#08x!\n", | ||
123 | ref_offset(ref2), jeb->offset); | ||
124 | jffs2_dbg_dump_node_refs(c, jeb); | ||
125 | jffs2_dbg_dump_block_lists(c); | ||
126 | BUG(); | ||
127 | |||
128 | } | ||
129 | if (ref_flags(ref2) == REF_UNCHECKED) | ||
130 | my_unchecked_size += totlen; | ||
131 | else if (!ref_obsolete(ref2)) | ||
132 | my_used_size += totlen; | ||
133 | else | ||
134 | my_dirty_size += totlen; | ||
135 | |||
136 | if ((!ref2->next_phys) != (ref2 == jeb->last_node)) { | ||
137 | printk(KERN_ERR "node_ref for node at %#08x (mem %p) has next_phys at %#08x (mem %p), " | ||
138 | "last_node is at %#08x (mem %p)\n", | ||
139 | ref_offset(ref2), ref2, ref_offset(ref2->next_phys), ref2->next_phys, | ||
140 | ref_offset(jeb->last_node), jeb->last_node); | ||
141 | jffs2_dbg_dump_node_refs(c, jeb); | ||
142 | jffs2_dbg_dump_block_lists(c); | ||
143 | BUG(); | ||
144 | } | ||
145 | ref2 = ref2->next_phys; | ||
146 | } | ||
147 | |||
148 | if (my_used_size != jeb->used_size) { | ||
149 | printk(KERN_ERR "Calculated used size %#08x != stored used size %#08x\n", | ||
150 | my_used_size, jeb->used_size); | ||
151 | jffs2_dbg_dump_node_refs(c, jeb); | ||
152 | jffs2_dbg_dump_block_lists(c); | ||
153 | BUG(); | ||
154 | } | ||
155 | |||
156 | if (my_unchecked_size != jeb->unchecked_size) { | ||
157 | printk(KERN_ERR "Calculated unchecked size %#08x != stored unchecked size %#08x\n", | ||
158 | my_unchecked_size, jeb->unchecked_size); | ||
159 | jffs2_dbg_dump_node_refs(c, jeb); | ||
160 | jffs2_dbg_dump_block_lists(c); | ||
161 | BUG(); | ||
162 | } | ||
163 | |||
164 | if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) { | ||
165 | printk(KERN_ERR "Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n", | ||
166 | my_dirty_size, jeb->dirty_size + jeb->wasted_size); | ||
167 | jffs2_dbg_dump_node_refs(c, jeb); | ||
168 | jffs2_dbg_dump_block_lists(c); | ||
169 | BUG(); | ||
170 | } | ||
171 | |||
172 | if (jeb->free_size == 0 | ||
173 | && my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) { | ||
174 | printk(KERN_ERR "The sum of all nodes in block (%#x) != size of block (%#x)\n", | ||
175 | my_used_size + my_unchecked_size + my_dirty_size, | ||
176 | c->sector_size); | ||
177 | jffs2_dbg_dump_node_refs(c, jeb); | ||
178 | jffs2_dbg_dump_block_lists(c); | ||
179 | BUG(); | ||
180 | } | ||
181 | } | ||
182 | #endif /* JFFS2_PARANOIA_CHECKS */ | ||
183 | |||
184 | #if defined(JFFS2_PARANOIA_CHECKS) || (CONFIG_JFFS2_FS_DEBUG > 0) | ||
185 | /* | ||
186 | * Dump the node_refs of the 'jeb' JFFS2 eraseblock. | ||
187 | */ | ||
188 | void | ||
189 | jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) | ||
190 | { | ||
191 | struct jffs2_raw_node_ref *ref; | ||
192 | int i = 0; | ||
193 | |||
194 | if (!jeb->first_node) { | ||
195 | printk(KERN_DEBUG "no nodes in block %#08x\n", jeb->offset); | ||
196 | return; | ||
197 | } | ||
198 | |||
199 | printk(KERN_DEBUG); | ||
200 | for (ref = jeb->first_node; ; ref = ref->next_phys) { | ||
201 | printk("%#08x(%#x)", ref_offset(ref), ref->__totlen); | ||
202 | if (ref->next_phys) | ||
203 | printk("->"); | ||
204 | else | ||
205 | break; | ||
206 | if (++i == 4) { | ||
207 | i = 0; | ||
208 | printk("\n" KERN_DEBUG); | ||
209 | } | ||
210 | } | ||
211 | printk("\n"); | ||
212 | } | ||
213 | |||
214 | void | ||
215 | jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c) | ||
216 | { | ||
217 | printk(KERN_DEBUG "flash_size: %#08x\n", c->flash_size); | ||
218 | printk(KERN_DEBUG "used_size: %#08x\n", c->used_size); | ||
219 | printk(KERN_DEBUG "dirty_size: %#08x\n", c->dirty_size); | ||
220 | printk(KERN_DEBUG "wasted_size: %#08x\n", c->wasted_size); | ||
221 | printk(KERN_DEBUG "unchecked_size: %#08x\n", c->unchecked_size); | ||
222 | printk(KERN_DEBUG "free_size: %#08x\n", c->free_size); | ||
223 | printk(KERN_DEBUG "erasing_size: %#08x\n", c->erasing_size); | ||
224 | printk(KERN_DEBUG "bad_size: %#08x\n", c->bad_size); | ||
225 | printk(KERN_DEBUG "sector_size: %#08x\n", c->sector_size); | ||
226 | printk(KERN_DEBUG "jffs2_reserved_blocks size: %#08x\n", | ||
227 | c->sector_size * c->resv_blocks_write); | ||
228 | |||
229 | if (c->nextblock) | ||
230 | printk(KERN_DEBUG "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, " | ||
231 | "unchecked %#08x, free %#08x)\n", | ||
232 | c->nextblock->offset, c->nextblock->used_size, | ||
233 | c->nextblock->dirty_size, c->nextblock->wasted_size, | ||
234 | c->nextblock->unchecked_size, c->nextblock->free_size); | ||
235 | else | ||
236 | printk(KERN_DEBUG "nextblock: NULL\n"); | ||
237 | |||
238 | if (c->gcblock) | ||
239 | printk(KERN_DEBUG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, " | ||
240 | "unchecked %#08x, free %#08x)\n", | ||
241 | c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size, | ||
242 | c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size); | ||
243 | else | ||
244 | printk(KERN_DEBUG "gcblock: NULL\n"); | ||
245 | |||
246 | if (list_empty(&c->clean_list)) { | ||
247 | printk(KERN_DEBUG "clean_list: empty\n"); | ||
248 | } else { | ||
249 | struct list_head *this; | ||
250 | int numblocks = 0; | ||
251 | uint32_t dirty = 0; | ||
252 | |||
253 | list_for_each(this, &c->clean_list) { | ||
254 | struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); | ||
255 | numblocks ++; | ||
256 | dirty += jeb->wasted_size; | ||
257 | if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { | ||
258 | printk(KERN_DEBUG "clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " | ||
259 | "unchecked %#08x, free %#08x)\n", | ||
260 | jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, | ||
261 | jeb->unchecked_size, jeb->free_size); | ||
262 | } | ||
263 | } | ||
264 | |||
265 | printk (KERN_DEBUG "Contains %d blocks with total wasted size %u, average wasted size: %u\n", | ||
266 | numblocks, dirty, dirty / numblocks); | ||
267 | } | ||
268 | |||
269 | if (list_empty(&c->very_dirty_list)) { | ||
270 | printk(KERN_DEBUG "very_dirty_list: empty\n"); | ||
271 | } else { | ||
272 | struct list_head *this; | ||
273 | int numblocks = 0; | ||
274 | uint32_t dirty = 0; | ||
275 | |||
276 | list_for_each(this, &c->very_dirty_list) { | ||
277 | struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); | ||
278 | |||
279 | numblocks ++; | ||
280 | dirty += jeb->dirty_size; | ||
281 | if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { | ||
282 | printk(KERN_DEBUG "very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " | ||
283 | "unchecked %#08x, free %#08x)\n", | ||
284 | jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, | ||
285 | jeb->unchecked_size, jeb->free_size); | ||
286 | } | ||
287 | } | ||
288 | |||
289 | printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n", | ||
290 | numblocks, dirty, dirty / numblocks); | ||
291 | } | ||
292 | |||
293 | if (list_empty(&c->dirty_list)) { | ||
294 | printk(KERN_DEBUG "dirty_list: empty\n"); | ||
295 | } else { | ||
296 | struct list_head *this; | ||
297 | int numblocks = 0; | ||
298 | uint32_t dirty = 0; | ||
299 | |||
300 | list_for_each(this, &c->dirty_list) { | ||
301 | struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); | ||
302 | |||
303 | numblocks ++; | ||
304 | dirty += jeb->dirty_size; | ||
305 | if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { | ||
306 | printk(KERN_DEBUG "dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " | ||
307 | "unchecked %#08x, free %#08x)\n", | ||
308 | jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, | ||
309 | jeb->unchecked_size, jeb->free_size); | ||
310 | } | ||
311 | } | ||
312 | |||
313 | printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n", | ||
314 | numblocks, dirty, dirty / numblocks); | ||
315 | } | ||
316 | |||
317 | if (list_empty(&c->erasable_list)) { | ||
318 | printk(KERN_DEBUG "erasable_list: empty\n"); | ||
319 | } else { | ||
320 | struct list_head *this; | ||
321 | |||
322 | list_for_each(this, &c->erasable_list) { | ||
323 | struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); | ||
324 | |||
325 | if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { | ||
326 | printk(KERN_DEBUG "erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " | ||
327 | "unchecked %#08x, free %#08x)\n", | ||
328 | jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, | ||
329 | jeb->unchecked_size, jeb->free_size); | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | |||
334 | if (list_empty(&c->erasing_list)) { | ||
335 | printk(KERN_DEBUG "erasing_list: empty\n"); | ||
336 | } else { | ||
337 | struct list_head *this; | ||
338 | |||
339 | list_for_each(this, &c->erasing_list) { | ||
340 | struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); | ||
341 | |||
342 | if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { | ||
343 | printk(KERN_DEBUG "erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " | ||
344 | "unchecked %#08x, free %#08x)\n", | ||
345 | jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, | ||
346 | jeb->unchecked_size, jeb->free_size); | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | |||
351 | if (list_empty(&c->erase_pending_list)) { | ||
352 | printk(KERN_DEBUG "erase_pending_list: empty\n"); | ||
353 | } else { | ||
354 | struct list_head *this; | ||
355 | |||
356 | list_for_each(this, &c->erase_pending_list) { | ||
357 | struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); | ||
358 | |||
359 | if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { | ||
360 | printk(KERN_DEBUG "erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " | ||
361 | "unchecked %#08x, free %#08x)\n", | ||
362 | jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, | ||
363 | jeb->unchecked_size, jeb->free_size); | ||
364 | } | ||
365 | } | ||
366 | } | ||
367 | |||
368 | if (list_empty(&c->erasable_pending_wbuf_list)) { | ||
369 | printk(KERN_DEBUG "erasable_pending_wbuf_list: empty\n"); | ||
370 | } else { | ||
371 | struct list_head *this; | ||
372 | |||
373 | list_for_each(this, &c->erasable_pending_wbuf_list) { | ||
374 | struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); | ||
375 | |||
376 | if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { | ||
377 | printk(KERN_DEBUG "erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, " | ||
378 | "wasted %#08x, unchecked %#08x, free %#08x)\n", | ||
379 | jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, | ||
380 | jeb->unchecked_size, jeb->free_size); | ||
381 | } | ||
382 | } | ||
383 | } | ||
384 | |||
385 | if (list_empty(&c->free_list)) { | ||
386 | printk(KERN_DEBUG "free_list: empty\n"); | ||
387 | } else { | ||
388 | struct list_head *this; | ||
389 | |||
390 | list_for_each(this, &c->free_list) { | ||
391 | struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); | ||
392 | |||
393 | if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { | ||
394 | printk(KERN_DEBUG "free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " | ||
395 | "unchecked %#08x, free %#08x)\n", | ||
396 | jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, | ||
397 | jeb->unchecked_size, jeb->free_size); | ||
398 | } | ||
399 | } | ||
400 | } | ||
401 | |||
402 | if (list_empty(&c->bad_list)) { | ||
403 | printk(KERN_DEBUG "bad_list: empty\n"); | ||
404 | } else { | ||
405 | struct list_head *this; | ||
406 | |||
407 | list_for_each(this, &c->bad_list) { | ||
408 | struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); | ||
409 | |||
410 | if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { | ||
411 | printk(KERN_DEBUG "bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " | ||
412 | "unchecked %#08x, free %#08x)\n", | ||
413 | jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, | ||
414 | jeb->unchecked_size, jeb->free_size); | ||
415 | } | ||
416 | } | ||
417 | } | ||
418 | |||
419 | if (list_empty(&c->bad_used_list)) { | ||
420 | printk(KERN_DEBUG "bad_used_list: empty\n"); | ||
421 | } else { | ||
422 | struct list_head *this; | ||
423 | |||
424 | list_for_each(this, &c->bad_used_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(KERN_DEBUG "bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " | ||
429 | "unchecked %#08x, free %#08x)\n", | ||
430 | jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, | ||
431 | jeb->unchecked_size, jeb->free_size); | ||
432 | } | ||
433 | } | ||
434 | } | ||
435 | } | ||
436 | |||
437 | void | ||
438 | jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f) | ||
439 | { | ||
440 | struct jffs2_node_frag *this = frag_first(&f->fragtree); | ||
441 | uint32_t lastofs = 0; | ||
442 | int buggy = 0; | ||
443 | |||
444 | printk(KERN_DEBUG "inode is ino #%u\n", f->inocache->ino); | ||
445 | while(this) { | ||
446 | if (this->node) | ||
447 | printk(KERN_DEBUG "frag %#04x-%#04x: %#08x(%d) on flash (*%p), left (%p), " | ||
448 | "right (%p), parent (%p)\n", | ||
449 | this->ofs, this->ofs+this->size, ref_offset(this->node->raw), | ||
450 | ref_flags(this->node->raw), this, frag_left(this), frag_right(this), | ||
451 | frag_parent(this)); | ||
452 | else | ||
453 | printk(KERN_DEBUG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n", | ||
454 | this->ofs, this->ofs+this->size, this, frag_left(this), | ||
455 | frag_right(this), frag_parent(this)); | ||
456 | if (this->ofs != lastofs) | ||
457 | buggy = 1; | ||
458 | lastofs = this->ofs + this->size; | ||
459 | this = frag_next(this); | ||
460 | } | ||
461 | |||
462 | if (f->metadata) | ||
463 | printk(KERN_DEBUG "metadata at 0x%08x\n", ref_offset(f->metadata->raw)); | ||
464 | |||
465 | if (buggy) { | ||
466 | printk(KERN_ERR "Error! %s(): Frag tree got a hole in it\n", __FUNCTION__); | ||
467 | BUG(); | ||
468 | } | ||
469 | } | ||
470 | |||
471 | #define JFFS3_BUFDUMP_BYTES_PER_LINE 8 | ||
472 | void | ||
473 | jffs2_dbg_dump_buffer(char *buf, int len, uint32_t offs) | ||
474 | { | ||
475 | int i = 0; | ||
476 | int skip = offs & ~(JFFS3_BUFDUMP_BYTES_PER_LINE - 1); | ||
477 | |||
478 | while (i < len) { | ||
479 | int j = 0; | ||
480 | |||
481 | printk(KERN_DEBUG "0x#x: \n"); | ||
482 | while (skip) { | ||
483 | printk(" "); | ||
484 | skip -= 1; | ||
485 | } | ||
486 | |||
487 | while (j < JFFS3_BUFDUMP_BYTES_PER_LINE) { | ||
488 | if (i + j < len) | ||
489 | printk(" %#02x", buf[i + j++]); | ||
490 | } | ||
491 | |||
492 | i += JFFS3_BUFDUMP_BYTES_PER_LINE; | ||
493 | } | ||
494 | } | ||
495 | #endif /* JFFS2_PARANOIA_CHECKS || CONFIG_JFFS2_FS_DEBUG > 0 */ | ||