aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2')
-rw-r--r--fs/jffs2/debug.c132
-rw-r--r--fs/jffs2/erase.c7
2 files changed, 136 insertions, 3 deletions
diff --git a/fs/jffs2/debug.c b/fs/jffs2/debug.c
index 660793107e92..590bdd6e0147 100644
--- a/fs/jffs2/debug.c
+++ b/fs/jffs2/debug.c
@@ -153,6 +153,135 @@ __jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c,
153 kfree(buf); 153 kfree(buf);
154} 154}
155 155
156void __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_complete_list, list) {
250 nr_counted++;
251 erasing += c->sector_size;
252 }
253 list_for_each_entry(jeb, &c->bad_list, list) {
254 nr_counted++;
255 bad += c->sector_size;
256 }
257
258#define check(sz) \
259 if (sz != c->sz##_size) { \
260 printk(KERN_WARNING #sz "_size mismatch counted 0x%x, c->" #sz "_size 0x%x\n", \
261 sz, c->sz##_size); \
262 dump = 1; \
263 }
264 check(free);
265 check(dirty);
266 check(used);
267 check(wasted);
268 check(unchecked);
269 check(bad);
270 check(erasing);
271#undef check
272
273 if (nr_counted != c->nr_blocks) {
274 printk(KERN_WARNING "%s counted only 0x%x blocks of 0x%x. Where are the others?\n",
275 __func__, nr_counted, c->nr_blocks);
276 dump = 1;
277 }
278
279 if (dump) {
280 __jffs2_dbg_dump_block_lists_nolock(c);
281 BUG();
282 }
283}
284
156/* 285/*
157 * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'. 286 * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'.
158 */ 287 */
@@ -229,6 +358,9 @@ __jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c,
229 } 358 }
230#endif 359#endif
231 360
361 if (!(c->flags & (JFFS2_SB_FLAG_BUILDING|JFFS2_SB_FLAG_SCANNING)))
362 __jffs2_dbg_superblock_counts(c);
363
232 return; 364 return;
233 365
234error: 366error:
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index bdc6a7bec802..65d91943fc2d 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -460,12 +460,13 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
460 if (c->cleanmarker_size && !jffs2_cleanmarker_oob(c)) 460 if (c->cleanmarker_size && !jffs2_cleanmarker_oob(c))
461 jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL, c->cleanmarker_size, NULL); 461 jffs2_link_node_ref(c, jeb, jeb->offset | REF_NORMAL, c->cleanmarker_size, NULL);
462 462
463 jffs2_dbg_acct_sanity_check_nolock(c,jeb);
464 jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
465
466 list_add_tail(&jeb->list, &c->free_list); 463 list_add_tail(&jeb->list, &c->free_list);
467 c->nr_erasing_blocks--; 464 c->nr_erasing_blocks--;
468 c->nr_free_blocks++; 465 c->nr_free_blocks++;
466
467 jffs2_dbg_acct_sanity_check_nolock(c, jeb);
468 jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
469
469 spin_unlock(&c->erase_completion_lock); 470 spin_unlock(&c->erase_completion_lock);
470 mutex_unlock(&c->erase_free_sem); 471 mutex_unlock(&c->erase_free_sem);
471 wake_up(&c->erase_wait); 472 wake_up(&c->erase_wait);