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