diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-25 15:25:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-25 15:25:48 -0400 |
commit | 7e97b28309edc5669ced2bb1371704e8f8d084e3 (patch) | |
tree | 9605694b00b4233a730ad86ea6d395cf59efc905 /fs/jffs2/debug.c | |
parent | 5421d059068341b3f21df1a21c2ba9175e55ebef (diff) | |
parent | 3887ed5231fb6f339f36c3a0297c996cd1a1dad9 (diff) |
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: (82 commits)
[MTD] m25p80: Add Support for ATMEL AT25DF641 64-Megabit SPI Flash
[MTD] m25p80: add FAST_READ access support to M25Pxx
[MTD] [NAND] bf5xx_nand: Avoid crash if bfin_mac is installed.
[MTD] [NAND] at91_nand: control NCE signal
[MTD] [NAND] AT91 hardware ECC compile fix for at91sam9263 / at91sam9260
[MTD] [NAND] Hardware ECC controller on at91sam9263 / at91sam9260
[JFFS2] Introduce dbg_readinode2 log level, use it to shut read_dnode() up
[JFFS2] Fix jffs2_reserve_space() when all blocks are pending erasure.
[JFFS2] Add erase_checking_list to hold blocks being marked.
UBI: add a message
[JFFS2] Return values of jffs2_block_check_erase error paths
[MTD] Clean up AR7 partition map support
[MTD] [NOR] Fix Intel CFI driver for collie flash
[JFFS2] Finally remove redundant ref->__totlen field.
[JFFS2] Honour TEST_TOTLEN macro in debugging code. ref->__totlen is going!
[JFFS2] Add paranoia debugging for superblock counts
[JFFS2] Fix free space leak with in-band cleanmarkers
[JFFS2] Self-sufficient #includes in jffs2_fs_i.h: include <linux/mutex.h>
[MTD] [NAND] Verify probe by retrying to checking the results match
[MTD] [NAND] S3C2410 Allow ECC disable to be specified by the board
...
Diffstat (limited to 'fs/jffs2/debug.c')
-rw-r--r-- | fs/jffs2/debug.c | 164 |
1 files changed, 159 insertions, 5 deletions
diff --git a/fs/jffs2/debug.c b/fs/jffs2/debug.c index 3a32c64ed497..5544d31c066b 100644 --- a/fs/jffs2/debug.c +++ b/fs/jffs2/debug.c | |||
@@ -62,9 +62,9 @@ __jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c, | |||
62 | void | 62 | void |
63 | __jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f) | 63 | __jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f) |
64 | { | 64 | { |
65 | down(&f->sem); | 65 | mutex_lock(&f->sem); |
66 | __jffs2_dbg_fragtree_paranoia_check_nolock(f); | 66 | __jffs2_dbg_fragtree_paranoia_check_nolock(f); |
67 | up(&f->sem); | 67 | mutex_unlock(&f->sem); |
68 | } | 68 | } |
69 | 69 | ||
70 | void | 70 | void |
@@ -153,6 +153,139 @@ __jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c, | |||
153 | kfree(buf); | 153 | kfree(buf); |
154 | } | 154 | } |
155 | 155 | ||
156 | void __jffs2_dbg_superblock_counts(struct jffs2_sb_info *c) | ||
157 | { | ||
158 | struct jffs2_eraseblock *jeb; | ||
159 | uint32_t free = 0, dirty = 0, used = 0, wasted = 0, | ||
160 | erasing = 0, bad = 0, unchecked = 0; | ||
161 | int nr_counted = 0; | ||
162 | int dump = 0; | ||
163 | |||
164 | if (c->gcblock) { | ||
165 | nr_counted++; | ||
166 | free += c->gcblock->free_size; | ||
167 | dirty += c->gcblock->dirty_size; | ||
168 | used += c->gcblock->used_size; | ||
169 | wasted += c->gcblock->wasted_size; | ||
170 | unchecked += c->gcblock->unchecked_size; | ||
171 | } | ||
172 | if (c->nextblock) { | ||
173 | nr_counted++; | ||
174 | free += c->nextblock->free_size; | ||
175 | dirty += c->nextblock->dirty_size; | ||
176 | used += c->nextblock->used_size; | ||
177 | wasted += c->nextblock->wasted_size; | ||
178 | unchecked += c->nextblock->unchecked_size; | ||
179 | } | ||
180 | list_for_each_entry(jeb, &c->clean_list, list) { | ||
181 | nr_counted++; | ||
182 | free += jeb->free_size; | ||
183 | dirty += jeb->dirty_size; | ||
184 | used += jeb->used_size; | ||
185 | wasted += jeb->wasted_size; | ||
186 | unchecked += jeb->unchecked_size; | ||
187 | } | ||
188 | list_for_each_entry(jeb, &c->very_dirty_list, list) { | ||
189 | nr_counted++; | ||
190 | free += jeb->free_size; | ||
191 | dirty += jeb->dirty_size; | ||
192 | used += jeb->used_size; | ||
193 | wasted += jeb->wasted_size; | ||
194 | unchecked += jeb->unchecked_size; | ||
195 | } | ||
196 | list_for_each_entry(jeb, &c->dirty_list, list) { | ||
197 | nr_counted++; | ||
198 | free += jeb->free_size; | ||
199 | dirty += jeb->dirty_size; | ||
200 | used += jeb->used_size; | ||
201 | wasted += jeb->wasted_size; | ||
202 | unchecked += jeb->unchecked_size; | ||
203 | } | ||
204 | list_for_each_entry(jeb, &c->erasable_list, list) { | ||
205 | nr_counted++; | ||
206 | free += jeb->free_size; | ||
207 | dirty += jeb->dirty_size; | ||
208 | used += jeb->used_size; | ||
209 | wasted += jeb->wasted_size; | ||
210 | unchecked += jeb->unchecked_size; | ||
211 | } | ||
212 | list_for_each_entry(jeb, &c->erasable_pending_wbuf_list, list) { | ||
213 | nr_counted++; | ||
214 | free += jeb->free_size; | ||
215 | dirty += jeb->dirty_size; | ||
216 | used += jeb->used_size; | ||
217 | wasted += jeb->wasted_size; | ||
218 | unchecked += jeb->unchecked_size; | ||
219 | } | ||
220 | list_for_each_entry(jeb, &c->erase_pending_list, list) { | ||
221 | nr_counted++; | ||
222 | free += jeb->free_size; | ||
223 | dirty += jeb->dirty_size; | ||
224 | used += jeb->used_size; | ||
225 | wasted += jeb->wasted_size; | ||
226 | unchecked += jeb->unchecked_size; | ||
227 | } | ||
228 | list_for_each_entry(jeb, &c->free_list, list) { | ||
229 | nr_counted++; | ||
230 | free += jeb->free_size; | ||
231 | dirty += jeb->dirty_size; | ||
232 | used += jeb->used_size; | ||
233 | wasted += jeb->wasted_size; | ||
234 | unchecked += jeb->unchecked_size; | ||
235 | } | ||
236 | list_for_each_entry(jeb, &c->bad_used_list, list) { | ||
237 | nr_counted++; | ||
238 | free += jeb->free_size; | ||
239 | dirty += jeb->dirty_size; | ||
240 | used += jeb->used_size; | ||
241 | wasted += jeb->wasted_size; | ||
242 | unchecked += jeb->unchecked_size; | ||
243 | } | ||
244 | |||
245 | list_for_each_entry(jeb, &c->erasing_list, list) { | ||
246 | nr_counted++; | ||
247 | erasing += c->sector_size; | ||
248 | } | ||
249 | list_for_each_entry(jeb, &c->erase_checking_list, list) { | ||
250 | nr_counted++; | ||
251 | erasing += c->sector_size; | ||
252 | } | ||
253 | list_for_each_entry(jeb, &c->erase_complete_list, list) { | ||
254 | nr_counted++; | ||
255 | erasing += c->sector_size; | ||
256 | } | ||
257 | list_for_each_entry(jeb, &c->bad_list, list) { | ||
258 | nr_counted++; | ||
259 | bad += c->sector_size; | ||
260 | } | ||
261 | |||
262 | #define check(sz) \ | ||
263 | if (sz != c->sz##_size) { \ | ||
264 | printk(KERN_WARNING #sz "_size mismatch counted 0x%x, c->" #sz "_size 0x%x\n", \ | ||
265 | sz, c->sz##_size); \ | ||
266 | dump = 1; \ | ||
267 | } | ||
268 | check(free); | ||
269 | check(dirty); | ||
270 | check(used); | ||
271 | check(wasted); | ||
272 | check(unchecked); | ||
273 | check(bad); | ||
274 | check(erasing); | ||
275 | #undef check | ||
276 | |||
277 | if (nr_counted != c->nr_blocks) { | ||
278 | printk(KERN_WARNING "%s counted only 0x%x blocks of 0x%x. Where are the others?\n", | ||
279 | __func__, nr_counted, c->nr_blocks); | ||
280 | dump = 1; | ||
281 | } | ||
282 | |||
283 | if (dump) { | ||
284 | __jffs2_dbg_dump_block_lists_nolock(c); | ||
285 | BUG(); | ||
286 | } | ||
287 | } | ||
288 | |||
156 | /* | 289 | /* |
157 | * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'. | 290 | * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'. |
158 | */ | 291 | */ |
@@ -229,6 +362,9 @@ __jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c, | |||
229 | } | 362 | } |
230 | #endif | 363 | #endif |
231 | 364 | ||
365 | if (!(c->flags & (JFFS2_SB_FLAG_BUILDING|JFFS2_SB_FLAG_SCANNING))) | ||
366 | __jffs2_dbg_superblock_counts(c); | ||
367 | |||
232 | return; | 368 | return; |
233 | 369 | ||
234 | error: | 370 | error: |
@@ -268,7 +404,10 @@ __jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c, | |||
268 | 404 | ||
269 | printk(JFFS2_DBG); | 405 | printk(JFFS2_DBG); |
270 | for (ref = jeb->first_node; ; ref = ref_next(ref)) { | 406 | for (ref = jeb->first_node; ; ref = ref_next(ref)) { |
271 | printk("%#08x(%#x)", ref_offset(ref), ref->__totlen); | 407 | printk("%#08x", ref_offset(ref)); |
408 | #ifdef TEST_TOTLEN | ||
409 | printk("(%x)", ref->__totlen); | ||
410 | #endif | ||
272 | if (ref_next(ref)) | 411 | if (ref_next(ref)) |
273 | printk("->"); | 412 | printk("->"); |
274 | else | 413 | else |
@@ -447,6 +586,21 @@ __jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c) | |||
447 | } | 586 | } |
448 | } | 587 | } |
449 | } | 588 | } |
589 | if (list_empty(&c->erase_checking_list)) { | ||
590 | printk(JFFS2_DBG "erase_checking_list: empty\n"); | ||
591 | } else { | ||
592 | struct list_head *this; | ||
593 | |||
594 | list_for_each(this, &c->erase_checking_list) { | ||
595 | struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); | ||
596 | |||
597 | if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { | ||
598 | printk(JFFS2_DBG "erase_checking_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n", | ||
599 | jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, | ||
600 | jeb->unchecked_size, jeb->free_size); | ||
601 | } | ||
602 | } | ||
603 | } | ||
450 | 604 | ||
451 | if (list_empty(&c->erase_pending_list)) { | 605 | if (list_empty(&c->erase_pending_list)) { |
452 | printk(JFFS2_DBG "erase_pending_list: empty\n"); | 606 | printk(JFFS2_DBG "erase_pending_list: empty\n"); |
@@ -532,9 +686,9 @@ __jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c) | |||
532 | void | 686 | void |
533 | __jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f) | 687 | __jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f) |
534 | { | 688 | { |
535 | down(&f->sem); | 689 | mutex_lock(&f->sem); |
536 | jffs2_dbg_dump_fragtree_nolock(f); | 690 | jffs2_dbg_dump_fragtree_nolock(f); |
537 | up(&f->sem); | 691 | mutex_unlock(&f->sem); |
538 | } | 692 | } |
539 | 693 | ||
540 | void | 694 | void |