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