|
@@ -153,6 +153,135 @@ __jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
|
|
|
kfree(buf);
|
|
|
}
|
|
|
|
|
|
+void __jffs2_dbg_superblock_counts(struct jffs2_sb_info *c)
|
|
|
+{
|
|
|
+ struct jffs2_eraseblock *jeb;
|
|
|
+ uint32_t free = 0, dirty = 0, used = 0, wasted = 0,
|
|
|
+ erasing = 0, bad = 0, unchecked = 0;
|
|
|
+ int nr_counted = 0;
|
|
|
+ int dump = 0;
|
|
|
+
|
|
|
+ if (c->gcblock) {
|
|
|
+ nr_counted++;
|
|
|
+ free += c->gcblock->free_size;
|
|
|
+ dirty += c->gcblock->dirty_size;
|
|
|
+ used += c->gcblock->used_size;
|
|
|
+ wasted += c->gcblock->wasted_size;
|
|
|
+ unchecked += c->gcblock->unchecked_size;
|
|
|
+ }
|
|
|
+ if (c->nextblock) {
|
|
|
+ nr_counted++;
|
|
|
+ free += c->nextblock->free_size;
|
|
|
+ dirty += c->nextblock->dirty_size;
|
|
|
+ used += c->nextblock->used_size;
|
|
|
+ wasted += c->nextblock->wasted_size;
|
|
|
+ unchecked += c->nextblock->unchecked_size;
|
|
|
+ }
|
|
|
+ list_for_each_entry(jeb, &c->clean_list, list) {
|
|
|
+ nr_counted++;
|
|
|
+ free += jeb->free_size;
|
|
|
+ dirty += jeb->dirty_size;
|
|
|
+ used += jeb->used_size;
|
|
|
+ wasted += jeb->wasted_size;
|
|
|
+ unchecked += jeb->unchecked_size;
|
|
|
+ }
|
|
|
+ list_for_each_entry(jeb, &c->very_dirty_list, list) {
|
|
|
+ nr_counted++;
|
|
|
+ free += jeb->free_size;
|
|
|
+ dirty += jeb->dirty_size;
|
|
|
+ used += jeb->used_size;
|
|
|
+ wasted += jeb->wasted_size;
|
|
|
+ unchecked += jeb->unchecked_size;
|
|
|
+ }
|
|
|
+ list_for_each_entry(jeb, &c->dirty_list, list) {
|
|
|
+ nr_counted++;
|
|
|
+ free += jeb->free_size;
|
|
|
+ dirty += jeb->dirty_size;
|
|
|
+ used += jeb->used_size;
|
|
|
+ wasted += jeb->wasted_size;
|
|
|
+ unchecked += jeb->unchecked_size;
|
|
|
+ }
|
|
|
+ list_for_each_entry(jeb, &c->erasable_list, list) {
|
|
|
+ nr_counted++;
|
|
|
+ free += jeb->free_size;
|
|
|
+ dirty += jeb->dirty_size;
|
|
|
+ used += jeb->used_size;
|
|
|
+ wasted += jeb->wasted_size;
|
|
|
+ unchecked += jeb->unchecked_size;
|
|
|
+ }
|
|
|
+ list_for_each_entry(jeb, &c->erasable_pending_wbuf_list, list) {
|
|
|
+ nr_counted++;
|
|
|
+ free += jeb->free_size;
|
|
|
+ dirty += jeb->dirty_size;
|
|
|
+ used += jeb->used_size;
|
|
|
+ wasted += jeb->wasted_size;
|
|
|
+ unchecked += jeb->unchecked_size;
|
|
|
+ }
|
|
|
+ list_for_each_entry(jeb, &c->erase_pending_list, list) {
|
|
|
+ nr_counted++;
|
|
|
+ free += jeb->free_size;
|
|
|
+ dirty += jeb->dirty_size;
|
|
|
+ used += jeb->used_size;
|
|
|
+ wasted += jeb->wasted_size;
|
|
|
+ unchecked += jeb->unchecked_size;
|
|
|
+ }
|
|
|
+ list_for_each_entry(jeb, &c->free_list, list) {
|
|
|
+ nr_counted++;
|
|
|
+ free += jeb->free_size;
|
|
|
+ dirty += jeb->dirty_size;
|
|
|
+ used += jeb->used_size;
|
|
|
+ wasted += jeb->wasted_size;
|
|
|
+ unchecked += jeb->unchecked_size;
|
|
|
+ }
|
|
|
+ list_for_each_entry(jeb, &c->bad_used_list, list) {
|
|
|
+ nr_counted++;
|
|
|
+ free += jeb->free_size;
|
|
|
+ dirty += jeb->dirty_size;
|
|
|
+ used += jeb->used_size;
|
|
|
+ wasted += jeb->wasted_size;
|
|
|
+ unchecked += jeb->unchecked_size;
|
|
|
+ }
|
|
|
+
|
|
|
+ list_for_each_entry(jeb, &c->erasing_list, list) {
|
|
|
+ nr_counted++;
|
|
|
+ erasing += c->sector_size;
|
|
|
+ }
|
|
|
+ list_for_each_entry(jeb, &c->erase_complete_list, list) {
|
|
|
+ nr_counted++;
|
|
|
+ erasing += c->sector_size;
|
|
|
+ }
|
|
|
+ list_for_each_entry(jeb, &c->bad_list, list) {
|
|
|
+ nr_counted++;
|
|
|
+ bad += c->sector_size;
|
|
|
+ }
|
|
|
+
|
|
|
+#define check(sz) \
|
|
|
+ if (sz != c->sz##_size) { \
|
|
|
+ printk(KERN_WARNING #sz "_size mismatch counted 0x%x, c->" #sz "_size 0x%x\n", \
|
|
|
+ sz, c->sz##_size); \
|
|
|
+ dump = 1; \
|
|
|
+ }
|
|
|
+ check(free);
|
|
|
+ check(dirty);
|
|
|
+ check(used);
|
|
|
+ check(wasted);
|
|
|
+ check(unchecked);
|
|
|
+ check(bad);
|
|
|
+ check(erasing);
|
|
|
+#undef check
|
|
|
+
|
|
|
+ if (nr_counted != c->nr_blocks) {
|
|
|
+ printk(KERN_WARNING "%s counted only 0x%x blocks of 0x%x. Where are the others?\n",
|
|
|
+ __func__, nr_counted, c->nr_blocks);
|
|
|
+ dump = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (dump) {
|
|
|
+ __jffs2_dbg_dump_block_lists_nolock(c);
|
|
|
+ BUG();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
|
|
|
*/
|
|
@@ -229,6 +358,9 @@ __jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+ if (!(c->flags & (JFFS2_SB_FLAG_BUILDING|JFFS2_SB_FLAG_SCANNING)))
|
|
|
+ __jffs2_dbg_superblock_counts(c);
|
|
|
+
|
|
|
return;
|
|
|
|
|
|
error:
|