1 /* 2 * JFFS2 -- Journalling Flash File System, Version 2. 3 * 4 * Copyright © 2001-2007 Red Hat, Inc. 5 * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org> 6 * 7 * Created by David Woodhouse <dwmw2@infradead.org> 8 * 9 * For licensing information, see the file 'LICENCE' in this directory. 10 * 11 */ 12 13 #include <linux/kernel.h> 14 #include <linux/types.h> 15 #include <linux/pagemap.h> 16 #include <linux/crc32.h> 17 #include <linux/jffs2.h> 18 #include <linux/mtd/mtd.h> 19 #include <linux/slab.h> 20 #include "nodelist.h" 21 #include "debug.h" 22 23 #ifdef JFFS2_DBG_SANITY_CHECKS 24 25 void 26 __jffs2_dbg_acct_sanity_check_nolock(struct jffs2_sb_info *c, 27 struct jffs2_eraseblock *jeb) 28 { 29 if (unlikely(jeb && jeb->used_size + jeb->dirty_size + 30 jeb->free_size + jeb->wasted_size + 31 jeb->unchecked_size != c->sector_size)) { 32 JFFS2_ERROR("eeep, space accounting for block at 0x%08x is screwed.\n", jeb->offset); 33 JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n", 34 jeb->free_size, jeb->dirty_size, jeb->used_size, 35 jeb->wasted_size, jeb->unchecked_size, c->sector_size); 36 BUG(); 37 } 38 39 if (unlikely(c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size 40 + c->wasted_size + c->unchecked_size != c->flash_size)) { 41 JFFS2_ERROR("eeep, space accounting superblock info is screwed.\n"); 42 JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + erasing %#08x + bad %#08x + wasted %#08x + unchecked %#08x != total %#08x.\n", 43 c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size, 44 c->wasted_size, c->unchecked_size, c->flash_size); 45 BUG(); 46 } 47 } 48 49 void 50 __jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c, 51 struct jffs2_eraseblock *jeb) 52 { 53 spin_lock(&c->erase_completion_lock); 54 jffs2_dbg_acct_sanity_check_nolock(c, jeb); 55 spin_unlock(&c->erase_completion_lock); 56 } 57 58 #endif /* JFFS2_DBG_SANITY_CHECKS */ 59 60 #ifdef JFFS2_DBG_PARANOIA_CHECKS 61 /* 62 * Check the fragtree. 63 */ 64 void 65 __jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f) 66 { 67 mutex_lock(&f->sem); 68 __jffs2_dbg_fragtree_paranoia_check_nolock(f); 69 mutex_unlock(&f->sem); 70 } 71 72 void 73 __jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f) 74 { 75 struct jffs2_node_frag *frag; 76 int bitched = 0; 77 78 for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) { 79 struct jffs2_full_dnode *fn = frag->node; 80 81 if (!fn || !fn->raw) 82 continue; 83 84 if (ref_flags(fn->raw) == REF_PRISTINE) { 85 if (fn->frags > 1) { 86 JFFS2_ERROR("REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2.\n", 87 ref_offset(fn->raw), fn->frags); 88 bitched = 1; 89 } 90 91 /* A hole node which isn't multi-page should be garbage-collected 92 and merged anyway, so we just check for the frag size here, 93 rather than mucking around with actually reading the node 94 and checking the compression type, which is the real way 95 to tell a hole node. */ 96 if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag) 97 && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) { 98 JFFS2_ERROR("REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2.\n", 99 ref_offset(fn->raw)); 100 bitched = 1; 101 } 102 103 if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag) 104 && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) { 105 JFFS2_ERROR("REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2.\n", 106 ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size); 107 bitched = 1; 108 } 109 } 110 } 111 112 if (bitched) { 113 JFFS2_ERROR("fragtree is corrupted.\n"); 114 __jffs2_dbg_dump_fragtree_nolock(f); 115 BUG(); 116 } 117 } 118 119 /* 120 * Check if the flash contains all 0xFF before we start writing. 121 */ 122 void 123 __jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c, 124 uint32_t ofs, int len) 125 { 126 size_t retlen; 127 int ret, i; 128 unsigned char *buf; 129 130 buf = kmalloc(len, GFP_KERNEL); 131 if (!buf) 132 return; 133 134 ret = jffs2_flash_read(c, ofs, len, &retlen, buf); 135 if (ret || (retlen != len)) { 136 JFFS2_WARNING("read %d bytes failed or short. ret %d, retlen %zd.\n", 137 len, ret, retlen); 138 kfree(buf); 139 return; 140 } 141 142 ret = 0; 143 for (i = 0; i < len; i++) 144 if (buf[i] != 0xff) 145 ret = 1; 146 147 if (ret) { 148 JFFS2_ERROR("argh, about to write node to %#08x on flash, but there are data already there. The first corrupted byte is at %#08x offset.\n", 149 ofs, ofs + i); 150 __jffs2_dbg_dump_buffer(buf, len, ofs); 151 kfree(buf); 152 BUG(); 153 } 154 155 kfree(buf); 156 } 157 158 void __jffs2_dbg_superblock_counts(struct jffs2_sb_info *c) 159 { 160 struct jffs2_eraseblock *jeb; 161 uint32_t free = 0, dirty = 0, used = 0, wasted = 0, 162 erasing = 0, bad = 0, unchecked = 0; 163 int nr_counted = 0; 164 int dump = 0; 165 166 if (c->gcblock) { 167 nr_counted++; 168 free += c->gcblock->free_size; 169 dirty += c->gcblock->dirty_size; 170 used += c->gcblock->used_size; 171 wasted += c->gcblock->wasted_size; 172 unchecked += c->gcblock->unchecked_size; 173 } 174 if (c->nextblock) { 175 nr_counted++; 176 free += c->nextblock->free_size; 177 dirty += c->nextblock->dirty_size; 178 used += c->nextblock->used_size; 179 wasted += c->nextblock->wasted_size; 180 unchecked += c->nextblock->unchecked_size; 181 } 182 list_for_each_entry(jeb, &c->clean_list, list) { 183 nr_counted++; 184 free += jeb->free_size; 185 dirty += jeb->dirty_size; 186 used += jeb->used_size; 187 wasted += jeb->wasted_size; 188 unchecked += jeb->unchecked_size; 189 } 190 list_for_each_entry(jeb, &c->very_dirty_list, list) { 191 nr_counted++; 192 free += jeb->free_size; 193 dirty += jeb->dirty_size; 194 used += jeb->used_size; 195 wasted += jeb->wasted_size; 196 unchecked += jeb->unchecked_size; 197 } 198 list_for_each_entry(jeb, &c->dirty_list, list) { 199 nr_counted++; 200 free += jeb->free_size; 201 dirty += jeb->dirty_size; 202 used += jeb->used_size; 203 wasted += jeb->wasted_size; 204 unchecked += jeb->unchecked_size; 205 } 206 list_for_each_entry(jeb, &c->erasable_list, list) { 207 nr_counted++; 208 free += jeb->free_size; 209 dirty += jeb->dirty_size; 210 used += jeb->used_size; 211 wasted += jeb->wasted_size; 212 unchecked += jeb->unchecked_size; 213 } 214 list_for_each_entry(jeb, &c->erasable_pending_wbuf_list, list) { 215 nr_counted++; 216 free += jeb->free_size; 217 dirty += jeb->dirty_size; 218 used += jeb->used_size; 219 wasted += jeb->wasted_size; 220 unchecked += jeb->unchecked_size; 221 } 222 list_for_each_entry(jeb, &c->erase_pending_list, list) { 223 nr_counted++; 224 free += jeb->free_size; 225 dirty += jeb->dirty_size; 226 used += jeb->used_size; 227 wasted += jeb->wasted_size; 228 unchecked += jeb->unchecked_size; 229 } 230 list_for_each_entry(jeb, &c->free_list, list) { 231 nr_counted++; 232 free += jeb->free_size; 233 dirty += jeb->dirty_size; 234 used += jeb->used_size; 235 wasted += jeb->wasted_size; 236 unchecked += jeb->unchecked_size; 237 } 238 list_for_each_entry(jeb, &c->bad_used_list, list) { 239 nr_counted++; 240 free += jeb->free_size; 241 dirty += jeb->dirty_size; 242 used += jeb->used_size; 243 wasted += jeb->wasted_size; 244 unchecked += jeb->unchecked_size; 245 } 246 247 list_for_each_entry(jeb, &c->erasing_list, list) { 248 nr_counted++; 249 erasing += c->sector_size; 250 } 251 list_for_each_entry(jeb, &c->erase_checking_list, list) { 252 nr_counted++; 253 erasing += c->sector_size; 254 } 255 list_for_each_entry(jeb, &c->erase_complete_list, list) { 256 nr_counted++; 257 erasing += c->sector_size; 258 } 259 list_for_each_entry(jeb, &c->bad_list, list) { 260 nr_counted++; 261 bad += c->sector_size; 262 } 263 264 #define check(sz) \ 265 do { \ 266 if (sz != c->sz##_size) { \ 267 pr_warn("%s_size mismatch counted 0x%x, c->%s_size 0x%x\n", \ 268 #sz, #sz, sz, c->sz##_size); \ 269 dump = 1; \ 270 } \ 271 } while (0) 272 273 check(free); 274 check(dirty); 275 check(used); 276 check(wasted); 277 check(unchecked); 278 check(bad); 279 check(erasing); 280 281 #undef check 282 283 if (nr_counted != c->nr_blocks) { 284 pr_warn("%s counted only 0x%x blocks of 0x%x. Where are the others?\n", 285 __func__, nr_counted, c->nr_blocks); 286 dump = 1; 287 } 288 289 if (dump) { 290 __jffs2_dbg_dump_block_lists_nolock(c); 291 BUG(); 292 } 293 } 294 295 /* 296 * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'. 297 */ 298 void 299 __jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c, 300 struct jffs2_eraseblock *jeb) 301 { 302 spin_lock(&c->erase_completion_lock); 303 __jffs2_dbg_acct_paranoia_check_nolock(c, jeb); 304 spin_unlock(&c->erase_completion_lock); 305 } 306 307 void 308 __jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c, 309 struct jffs2_eraseblock *jeb) 310 { 311 uint32_t my_used_size = 0; 312 uint32_t my_unchecked_size = 0; 313 uint32_t my_dirty_size = 0; 314 struct jffs2_raw_node_ref *ref2 = jeb->first_node; 315 316 while (ref2) { 317 uint32_t totlen = ref_totlen(c, jeb, ref2); 318 319 if (ref_offset(ref2) < jeb->offset || 320 ref_offset(ref2) > jeb->offset + c->sector_size) { 321 JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.\n", 322 ref_offset(ref2), jeb->offset); 323 goto error; 324 325 } 326 if (ref_flags(ref2) == REF_UNCHECKED) 327 my_unchecked_size += totlen; 328 else if (!ref_obsolete(ref2)) 329 my_used_size += totlen; 330 else 331 my_dirty_size += totlen; 332 333 if ((!ref_next(ref2)) != (ref2 == jeb->last_node)) { 334 JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next at %#08x (mem %p), last_node is at %#08x (mem %p).\n", 335 ref_offset(ref2), ref2, ref_offset(ref_next(ref2)), ref_next(ref2), 336 ref_offset(jeb->last_node), jeb->last_node); 337 goto error; 338 } 339 ref2 = ref_next(ref2); 340 } 341 342 if (my_used_size != jeb->used_size) { 343 JFFS2_ERROR("Calculated used size %#08x != stored used size %#08x.\n", 344 my_used_size, jeb->used_size); 345 goto error; 346 } 347 348 if (my_unchecked_size != jeb->unchecked_size) { 349 JFFS2_ERROR("Calculated unchecked size %#08x != stored unchecked size %#08x.\n", 350 my_unchecked_size, jeb->unchecked_size); 351 goto error; 352 } 353 354 #if 0 355 /* This should work when we implement ref->__totlen elemination */ 356 if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) { 357 JFFS2_ERROR("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n", 358 my_dirty_size, jeb->dirty_size + jeb->wasted_size); 359 goto error; 360 } 361 362 if (jeb->free_size == 0 363 && my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) { 364 JFFS2_ERROR("The sum of all nodes in block (%#x) != size of block (%#x)\n", 365 my_used_size + my_unchecked_size + my_dirty_size, 366 c->sector_size); 367 goto error; 368 } 369 #endif 370 371 if (!(c->flags & (JFFS2_SB_FLAG_BUILDING|JFFS2_SB_FLAG_SCANNING))) 372 __jffs2_dbg_superblock_counts(c); 373 374 return; 375 376 error: 377 __jffs2_dbg_dump_node_refs_nolock(c, jeb); 378 __jffs2_dbg_dump_jeb_nolock(jeb); 379 __jffs2_dbg_dump_block_lists_nolock(c); 380 BUG(); 381 382 } 383 #endif /* JFFS2_DBG_PARANOIA_CHECKS */ 384 385 #if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS) 386 /* 387 * Dump the node_refs of the 'jeb' JFFS2 eraseblock. 388 */ 389 void 390 __jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c, 391 struct jffs2_eraseblock *jeb) 392 { 393 spin_lock(&c->erase_completion_lock); 394 __jffs2_dbg_dump_node_refs_nolock(c, jeb); 395 spin_unlock(&c->erase_completion_lock); 396 } 397 398 void 399 __jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c, 400 struct jffs2_eraseblock *jeb) 401 { 402 struct jffs2_raw_node_ref *ref; 403 int i = 0; 404 405 printk(JFFS2_DBG_MSG_PREFIX " Dump node_refs of the eraseblock %#08x\n", jeb->offset); 406 if (!jeb->first_node) { 407 printk(JFFS2_DBG_MSG_PREFIX " no nodes in the eraseblock %#08x\n", jeb->offset); 408 return; 409 } 410 411 printk(JFFS2_DBG); 412 for (ref = jeb->first_node; ; ref = ref_next(ref)) { 413 printk("%#08x", ref_offset(ref)); 414 #ifdef TEST_TOTLEN 415 printk("(%x)", ref->__totlen); 416 #endif 417 if (ref_next(ref)) 418 printk("->"); 419 else 420 break; 421 if (++i == 4) { 422 i = 0; 423 printk("\n" JFFS2_DBG); 424 } 425 } 426 printk("\n"); 427 } 428 429 /* 430 * Dump an eraseblock's space accounting. 431 */ 432 void 433 __jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 434 { 435 spin_lock(&c->erase_completion_lock); 436 __jffs2_dbg_dump_jeb_nolock(jeb); 437 spin_unlock(&c->erase_completion_lock); 438 } 439 440 void 441 __jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb) 442 { 443 if (!jeb) 444 return; 445 446 printk(JFFS2_DBG_MSG_PREFIX " dump space accounting for the eraseblock at %#08x:\n", 447 jeb->offset); 448 449 printk(JFFS2_DBG "used_size: %#08x\n", jeb->used_size); 450 printk(JFFS2_DBG "dirty_size: %#08x\n", jeb->dirty_size); 451 printk(JFFS2_DBG "wasted_size: %#08x\n", jeb->wasted_size); 452 printk(JFFS2_DBG "unchecked_size: %#08x\n", jeb->unchecked_size); 453 printk(JFFS2_DBG "free_size: %#08x\n", jeb->free_size); 454 } 455 456 void 457 __jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c) 458 { 459 spin_lock(&c->erase_completion_lock); 460 __jffs2_dbg_dump_block_lists_nolock(c); 461 spin_unlock(&c->erase_completion_lock); 462 } 463 464 void 465 __jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c) 466 { 467 printk(JFFS2_DBG_MSG_PREFIX " dump JFFS2 blocks lists:\n"); 468 469 printk(JFFS2_DBG "flash_size: %#08x\n", c->flash_size); 470 printk(JFFS2_DBG "used_size: %#08x\n", c->used_size); 471 printk(JFFS2_DBG "dirty_size: %#08x\n", c->dirty_size); 472 printk(JFFS2_DBG "wasted_size: %#08x\n", c->wasted_size); 473 printk(JFFS2_DBG "unchecked_size: %#08x\n", c->unchecked_size); 474 printk(JFFS2_DBG "free_size: %#08x\n", c->free_size); 475 printk(JFFS2_DBG "erasing_size: %#08x\n", c->erasing_size); 476 printk(JFFS2_DBG "bad_size: %#08x\n", c->bad_size); 477 printk(JFFS2_DBG "sector_size: %#08x\n", c->sector_size); 478 printk(JFFS2_DBG "jffs2_reserved_blocks size: %#08x\n", 479 c->sector_size * c->resv_blocks_write); 480 481 if (c->nextblock) 482 printk(JFFS2_DBG "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n", 483 c->nextblock->offset, c->nextblock->used_size, 484 c->nextblock->dirty_size, c->nextblock->wasted_size, 485 c->nextblock->unchecked_size, c->nextblock->free_size); 486 else 487 printk(JFFS2_DBG "nextblock: NULL\n"); 488 489 if (c->gcblock) 490 printk(JFFS2_DBG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n", 491 c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size, 492 c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size); 493 else 494 printk(JFFS2_DBG "gcblock: NULL\n"); 495 496 if (list_empty(&c->clean_list)) { 497 printk(JFFS2_DBG "clean_list: empty\n"); 498 } else { 499 struct list_head *this; 500 int numblocks = 0; 501 uint32_t dirty = 0; 502 503 list_for_each(this, &c->clean_list) { 504 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 505 numblocks ++; 506 dirty += jeb->wasted_size; 507 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 508 printk(JFFS2_DBG "clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n", 509 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 510 jeb->unchecked_size, jeb->free_size); 511 } 512 } 513 514 printk (JFFS2_DBG "Contains %d blocks with total wasted size %u, average wasted size: %u\n", 515 numblocks, dirty, dirty / numblocks); 516 } 517 518 if (list_empty(&c->very_dirty_list)) { 519 printk(JFFS2_DBG "very_dirty_list: empty\n"); 520 } else { 521 struct list_head *this; 522 int numblocks = 0; 523 uint32_t dirty = 0; 524 525 list_for_each(this, &c->very_dirty_list) { 526 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 527 528 numblocks ++; 529 dirty += jeb->dirty_size; 530 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 531 printk(JFFS2_DBG "very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n", 532 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 533 jeb->unchecked_size, jeb->free_size); 534 } 535 } 536 537 printk (JFFS2_DBG "Contains %d blocks with total dirty size %u, average dirty size: %u\n", 538 numblocks, dirty, dirty / numblocks); 539 } 540 541 if (list_empty(&c->dirty_list)) { 542 printk(JFFS2_DBG "dirty_list: empty\n"); 543 } else { 544 struct list_head *this; 545 int numblocks = 0; 546 uint32_t dirty = 0; 547 548 list_for_each(this, &c->dirty_list) { 549 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 550 551 numblocks ++; 552 dirty += jeb->dirty_size; 553 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 554 printk(JFFS2_DBG "dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n", 555 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 556 jeb->unchecked_size, jeb->free_size); 557 } 558 } 559 560 printk (JFFS2_DBG "contains %d blocks with total dirty size %u, average dirty size: %u\n", 561 numblocks, dirty, dirty / numblocks); 562 } 563 564 if (list_empty(&c->erasable_list)) { 565 printk(JFFS2_DBG "erasable_list: empty\n"); 566 } else { 567 struct list_head *this; 568 569 list_for_each(this, &c->erasable_list) { 570 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 571 572 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 573 printk(JFFS2_DBG "erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n", 574 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 575 jeb->unchecked_size, jeb->free_size); 576 } 577 } 578 } 579 580 if (list_empty(&c->erasing_list)) { 581 printk(JFFS2_DBG "erasing_list: empty\n"); 582 } else { 583 struct list_head *this; 584 585 list_for_each(this, &c->erasing_list) { 586 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 587 588 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 589 printk(JFFS2_DBG "erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n", 590 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 591 jeb->unchecked_size, jeb->free_size); 592 } 593 } 594 } 595 if (list_empty(&c->erase_checking_list)) { 596 printk(JFFS2_DBG "erase_checking_list: empty\n"); 597 } else { 598 struct list_head *this; 599 600 list_for_each(this, &c->erase_checking_list) { 601 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 602 603 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 604 printk(JFFS2_DBG "erase_checking_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n", 605 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 606 jeb->unchecked_size, jeb->free_size); 607 } 608 } 609 } 610 611 if (list_empty(&c->erase_pending_list)) { 612 printk(JFFS2_DBG "erase_pending_list: empty\n"); 613 } else { 614 struct list_head *this; 615 616 list_for_each(this, &c->erase_pending_list) { 617 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 618 619 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 620 printk(JFFS2_DBG "erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n", 621 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 622 jeb->unchecked_size, jeb->free_size); 623 } 624 } 625 } 626 627 if (list_empty(&c->erasable_pending_wbuf_list)) { 628 printk(JFFS2_DBG "erasable_pending_wbuf_list: empty\n"); 629 } else { 630 struct list_head *this; 631 632 list_for_each(this, &c->erasable_pending_wbuf_list) { 633 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 634 635 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 636 printk(JFFS2_DBG "erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n", 637 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 638 jeb->unchecked_size, jeb->free_size); 639 } 640 } 641 } 642 643 if (list_empty(&c->free_list)) { 644 printk(JFFS2_DBG "free_list: empty\n"); 645 } else { 646 struct list_head *this; 647 648 list_for_each(this, &c->free_list) { 649 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 650 651 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 652 printk(JFFS2_DBG "free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n", 653 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 654 jeb->unchecked_size, jeb->free_size); 655 } 656 } 657 } 658 659 if (list_empty(&c->bad_list)) { 660 printk(JFFS2_DBG "bad_list: empty\n"); 661 } else { 662 struct list_head *this; 663 664 list_for_each(this, &c->bad_list) { 665 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 666 667 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 668 printk(JFFS2_DBG "bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n", 669 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 670 jeb->unchecked_size, jeb->free_size); 671 } 672 } 673 } 674 675 if (list_empty(&c->bad_used_list)) { 676 printk(JFFS2_DBG "bad_used_list: empty\n"); 677 } else { 678 struct list_head *this; 679 680 list_for_each(this, &c->bad_used_list) { 681 struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 682 683 if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 684 printk(JFFS2_DBG "bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, unchecked %#08x, free %#08x)\n", 685 jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 686 jeb->unchecked_size, jeb->free_size); 687 } 688 } 689 } 690 } 691 692 void 693 __jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f) 694 { 695 mutex_lock(&f->sem); 696 jffs2_dbg_dump_fragtree_nolock(f); 697 mutex_unlock(&f->sem); 698 } 699 700 void 701 __jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f) 702 { 703 struct jffs2_node_frag *this = frag_first(&f->fragtree); 704 uint32_t lastofs = 0; 705 int buggy = 0; 706 707 printk(JFFS2_DBG_MSG_PREFIX " dump fragtree of ino #%u\n", f->inocache->ino); 708 while(this) { 709 if (this->node) 710 printk(JFFS2_DBG "frag %#04x-%#04x: %#08x(%d) on flash (*%p), left (%p), right (%p), parent (%p)\n", 711 this->ofs, this->ofs+this->size, ref_offset(this->node->raw), 712 ref_flags(this->node->raw), this, frag_left(this), frag_right(this), 713 frag_parent(this)); 714 else 715 printk(JFFS2_DBG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n", 716 this->ofs, this->ofs+this->size, this, frag_left(this), 717 frag_right(this), frag_parent(this)); 718 if (this->ofs != lastofs) 719 buggy = 1; 720 lastofs = this->ofs + this->size; 721 this = frag_next(this); 722 } 723 724 if (f->metadata) 725 printk(JFFS2_DBG "metadata at 0x%08x\n", ref_offset(f->metadata->raw)); 726 727 if (buggy) { 728 JFFS2_ERROR("frag tree got a hole in it.\n"); 729 BUG(); 730 } 731 } 732 733 #define JFFS2_BUFDUMP_BYTES_PER_LINE 32 734 void 735 __jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs) 736 { 737 int skip; 738 int i; 739 740 printk(JFFS2_DBG_MSG_PREFIX " dump from offset %#08x to offset %#08x (%x bytes).\n", 741 offs, offs + len, len); 742 i = skip = offs % JFFS2_BUFDUMP_BYTES_PER_LINE; 743 offs = offs & ~(JFFS2_BUFDUMP_BYTES_PER_LINE - 1); 744 745 if (skip != 0) 746 printk(JFFS2_DBG "%#08x: ", offs); 747 748 while (skip--) 749 printk(" "); 750 751 while (i < len) { 752 if ((i % JFFS2_BUFDUMP_BYTES_PER_LINE) == 0 && i != len -1) { 753 if (i != 0) 754 printk("\n"); 755 offs += JFFS2_BUFDUMP_BYTES_PER_LINE; 756 printk(JFFS2_DBG "%0#8x: ", offs); 757 } 758 759 printk("%02x ", buf[i]); 760 761 i += 1; 762 } 763 764 printk("\n"); 765 } 766 767 /* 768 * Dump a JFFS2 node. 769 */ 770 void 771 __jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs) 772 { 773 union jffs2_node_union node; 774 int len = sizeof(union jffs2_node_union); 775 size_t retlen; 776 uint32_t crc; 777 int ret; 778 779 printk(JFFS2_DBG_MSG_PREFIX " dump node at offset %#08x.\n", ofs); 780 781 ret = jffs2_flash_read(c, ofs, len, &retlen, (unsigned char *)&node); 782 if (ret || (retlen != len)) { 783 JFFS2_ERROR("read %d bytes failed or short. ret %d, retlen %zd.\n", 784 len, ret, retlen); 785 return; 786 } 787 788 printk(JFFS2_DBG "magic:\t%#04x\n", je16_to_cpu(node.u.magic)); 789 printk(JFFS2_DBG "nodetype:\t%#04x\n", je16_to_cpu(node.u.nodetype)); 790 printk(JFFS2_DBG "totlen:\t%#08x\n", je32_to_cpu(node.u.totlen)); 791 printk(JFFS2_DBG "hdr_crc:\t%#08x\n", je32_to_cpu(node.u.hdr_crc)); 792 793 crc = crc32(0, &node.u, sizeof(node.u) - 4); 794 if (crc != je32_to_cpu(node.u.hdr_crc)) { 795 JFFS2_ERROR("wrong common header CRC.\n"); 796 return; 797 } 798 799 if (je16_to_cpu(node.u.magic) != JFFS2_MAGIC_BITMASK && 800 je16_to_cpu(node.u.magic) != JFFS2_OLD_MAGIC_BITMASK) 801 { 802 JFFS2_ERROR("wrong node magic: %#04x instead of %#04x.\n", 803 je16_to_cpu(node.u.magic), JFFS2_MAGIC_BITMASK); 804 return; 805 } 806 807 switch(je16_to_cpu(node.u.nodetype)) { 808 809 case JFFS2_NODETYPE_INODE: 810 811 printk(JFFS2_DBG "the node is inode node\n"); 812 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.i.ino)); 813 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.i.version)); 814 printk(JFFS2_DBG "mode:\t%#08x\n", node.i.mode.m); 815 printk(JFFS2_DBG "uid:\t%#04x\n", je16_to_cpu(node.i.uid)); 816 printk(JFFS2_DBG "gid:\t%#04x\n", je16_to_cpu(node.i.gid)); 817 printk(JFFS2_DBG "isize:\t%#08x\n", je32_to_cpu(node.i.isize)); 818 printk(JFFS2_DBG "atime:\t%#08x\n", je32_to_cpu(node.i.atime)); 819 printk(JFFS2_DBG "mtime:\t%#08x\n", je32_to_cpu(node.i.mtime)); 820 printk(JFFS2_DBG "ctime:\t%#08x\n", je32_to_cpu(node.i.ctime)); 821 printk(JFFS2_DBG "offset:\t%#08x\n", je32_to_cpu(node.i.offset)); 822 printk(JFFS2_DBG "csize:\t%#08x\n", je32_to_cpu(node.i.csize)); 823 printk(JFFS2_DBG "dsize:\t%#08x\n", je32_to_cpu(node.i.dsize)); 824 printk(JFFS2_DBG "compr:\t%#02x\n", node.i.compr); 825 printk(JFFS2_DBG "usercompr:\t%#02x\n", node.i.usercompr); 826 printk(JFFS2_DBG "flags:\t%#04x\n", je16_to_cpu(node.i.flags)); 827 printk(JFFS2_DBG "data_crc:\t%#08x\n", je32_to_cpu(node.i.data_crc)); 828 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.i.node_crc)); 829 830 crc = crc32(0, &node.i, sizeof(node.i) - 8); 831 if (crc != je32_to_cpu(node.i.node_crc)) { 832 JFFS2_ERROR("wrong node header CRC.\n"); 833 return; 834 } 835 break; 836 837 case JFFS2_NODETYPE_DIRENT: 838 839 printk(JFFS2_DBG "the node is dirent node\n"); 840 printk(JFFS2_DBG "pino:\t%#08x\n", je32_to_cpu(node.d.pino)); 841 printk(JFFS2_DBG "version:\t%#08x\n", je32_to_cpu(node.d.version)); 842 printk(JFFS2_DBG "ino:\t%#08x\n", je32_to_cpu(node.d.ino)); 843 printk(JFFS2_DBG "mctime:\t%#08x\n", je32_to_cpu(node.d.mctime)); 844 printk(JFFS2_DBG "nsize:\t%#02x\n", node.d.nsize); 845 printk(JFFS2_DBG "type:\t%#02x\n", node.d.type); 846 printk(JFFS2_DBG "node_crc:\t%#08x\n", je32_to_cpu(node.d.node_crc)); 847 printk(JFFS2_DBG "name_crc:\t%#08x\n", je32_to_cpu(node.d.name_crc)); 848 849 node.d.name[node.d.nsize] = '\0'; 850 printk(JFFS2_DBG "name:\t\"%s\"\n", node.d.name); 851 852 crc = crc32(0, &node.d, sizeof(node.d) - 8); 853 if (crc != je32_to_cpu(node.d.node_crc)) { 854 JFFS2_ERROR("wrong node header CRC.\n"); 855 return; 856 } 857 break; 858 859 default: 860 printk(JFFS2_DBG "node type is unknown\n"); 861 break; 862 } 863 } 864 #endif /* JFFS2_DBG_DUMPS || JFFS2_DBG_PARANOIA_CHECKS */ 865