diff options
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 |
