1730554d9SArtem B. Bityutskiy /* 2730554d9SArtem B. Bityutskiy * JFFS2 -- Journalling Flash File System, Version 2. 3730554d9SArtem B. Bityutskiy * 4730554d9SArtem B. Bityutskiy * Copyright (C) 2001-2003 Red Hat, Inc. 5730554d9SArtem B. Bityutskiy * 6730554d9SArtem B. Bityutskiy * Created by David Woodhouse <dwmw2@infradead.org> 7730554d9SArtem B. Bityutskiy * 8730554d9SArtem B. Bityutskiy * For licensing information, see the file 'LICENCE' in this directory. 9730554d9SArtem B. Bityutskiy * 10730554d9SArtem B. Bityutskiy * $Id: debug.c,v 1.1 2005/07/17 06:56:20 dedekind Exp $ 11730554d9SArtem B. Bityutskiy * 12730554d9SArtem B. Bityutskiy */ 13730554d9SArtem B. Bityutskiy #include <linux/kernel.h> 14730554d9SArtem B. Bityutskiy #include <linux/pagemap.h> 15730554d9SArtem B. Bityutskiy #include "nodelist.h" 16730554d9SArtem B. Bityutskiy #include "debug.h" 17730554d9SArtem B. Bityutskiy 18730554d9SArtem B. Bityutskiy #ifdef JFFS2_DBG_PARANOIA_CHECKS 19730554d9SArtem B. Bityutskiy 20730554d9SArtem B. Bityutskiy void 21730554d9SArtem B. Bityutskiy jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f) 22730554d9SArtem B. Bityutskiy { 23730554d9SArtem B. Bityutskiy struct jffs2_node_frag *frag; 24730554d9SArtem B. Bityutskiy int bitched = 0; 25730554d9SArtem B. Bityutskiy 26730554d9SArtem B. Bityutskiy for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) { 27730554d9SArtem B. Bityutskiy struct jffs2_full_dnode *fn = frag->node; 28730554d9SArtem B. Bityutskiy 29730554d9SArtem B. Bityutskiy if (!fn || !fn->raw) 30730554d9SArtem B. Bityutskiy continue; 31730554d9SArtem B. Bityutskiy 32730554d9SArtem B. Bityutskiy if (ref_flags(fn->raw) == REF_PRISTINE) { 33730554d9SArtem B. Bityutskiy if (fn->frags > 1) { 34730554d9SArtem B. Bityutskiy printk(KERN_ERR "REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2\n", 35730554d9SArtem B. Bityutskiy ref_offset(fn->raw), fn->frags); 36730554d9SArtem B. Bityutskiy bitched = 1; 37730554d9SArtem B. Bityutskiy } 38730554d9SArtem B. Bityutskiy 39730554d9SArtem B. Bityutskiy /* A hole node which isn't multi-page should be garbage-collected 40730554d9SArtem B. Bityutskiy and merged anyway, so we just check for the frag size here, 41730554d9SArtem B. Bityutskiy rather than mucking around with actually reading the node 42730554d9SArtem B. Bityutskiy and checking the compression type, which is the real way 43730554d9SArtem B. Bityutskiy to tell a hole node. */ 44730554d9SArtem B. Bityutskiy if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag) 45730554d9SArtem B. Bityutskiy && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) { 46730554d9SArtem B. Bityutskiy printk(KERN_ERR "REF_PRISTINE node at 0x%08x had a previous non-hole frag " 47730554d9SArtem B. Bityutskiy "in the same page. Tell dwmw2\n", ref_offset(fn->raw)); 48730554d9SArtem B. Bityutskiy bitched = 1; 49730554d9SArtem B. Bityutskiy } 50730554d9SArtem B. Bityutskiy 51730554d9SArtem B. Bityutskiy if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag) 52730554d9SArtem B. Bityutskiy && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) { 53730554d9SArtem B. Bityutskiy printk(KERN_ERR "REF_PRISTINE node at 0x%08x (%08x-%08x) had a following " 54730554d9SArtem B. Bityutskiy "non-hole frag in the same page. Tell dwmw2\n", 55730554d9SArtem B. Bityutskiy ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size); 56730554d9SArtem B. Bityutskiy bitched = 1; 57730554d9SArtem B. Bityutskiy } 58730554d9SArtem B. Bityutskiy } 59730554d9SArtem B. Bityutskiy } 60730554d9SArtem B. Bityutskiy 61730554d9SArtem B. Bityutskiy if (bitched) { 62730554d9SArtem B. Bityutskiy printk(KERN_ERR "Fragtree is corrupted. Fragtree dump:\n"); 63730554d9SArtem B. Bityutskiy jffs2_dbg_dump_fragtree(f); 64730554d9SArtem B. Bityutskiy BUG(); 65730554d9SArtem B. Bityutskiy } 66730554d9SArtem B. Bityutskiy } 67730554d9SArtem B. Bityutskiy 68730554d9SArtem B. Bityutskiy /* 69730554d9SArtem B. Bityutskiy * Check if the flash contains all 0xFF before we start writing. 70730554d9SArtem B. Bityutskiy */ 71730554d9SArtem B. Bityutskiy void 72730554d9SArtem B. Bityutskiy jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c, uint32_t ofs, int len) 73730554d9SArtem B. Bityutskiy { 74730554d9SArtem B. Bityutskiy size_t retlen; 75730554d9SArtem B. Bityutskiy int ret, i; 76730554d9SArtem B. Bityutskiy unsigned char *buf; 77730554d9SArtem B. Bityutskiy 78730554d9SArtem B. Bityutskiy buf = kmalloc(len, GFP_KERNEL); 79730554d9SArtem B. Bityutskiy if (!buf) 80730554d9SArtem B. Bityutskiy return; 81730554d9SArtem B. Bityutskiy 82730554d9SArtem B. Bityutskiy ret = jffs2_flash_read(c, ofs, len, &retlen, buf); 83730554d9SArtem B. Bityutskiy if (ret || (retlen != len)) { 84730554d9SArtem B. Bityutskiy printk(KERN_WARNING "read %d bytes failed or short in %s(). ret %d, retlen %zd\n", 85730554d9SArtem B. Bityutskiy len, __FUNCTION__, ret, retlen); 86730554d9SArtem B. Bityutskiy kfree(buf); 87730554d9SArtem B. Bityutskiy return; 88730554d9SArtem B. Bityutskiy } 89730554d9SArtem B. Bityutskiy 90730554d9SArtem B. Bityutskiy ret = 0; 91730554d9SArtem B. Bityutskiy for (i = 0; i < len; i++) 92730554d9SArtem B. Bityutskiy if (buf[i] != 0xff) 93730554d9SArtem B. Bityutskiy ret = 1; 94730554d9SArtem B. Bityutskiy 95730554d9SArtem B. Bityutskiy if (ret) { 96730554d9SArtem B. Bityutskiy printk(KERN_ERR "ARGH. About to write node to %#08x on flash, but there are data " 97730554d9SArtem B. Bityutskiy "already there. The first corrupted byte is at %#08x.\n", ofs, ofs + i); 98730554d9SArtem B. Bityutskiy jffs2_dbg_dump_buffer(buf, len, ofs); 99730554d9SArtem B. Bityutskiy kfree(buf); 100730554d9SArtem B. Bityutskiy BUG(); 101730554d9SArtem B. Bityutskiy } 102730554d9SArtem B. Bityutskiy 103730554d9SArtem B. Bityutskiy kfree(buf); 104730554d9SArtem B. Bityutskiy } 105730554d9SArtem B. Bityutskiy 106730554d9SArtem B. Bityutskiy /* 107730554d9SArtem B. Bityutskiy * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'. 108730554d9SArtem B. Bityutskiy */ 109730554d9SArtem B. Bityutskiy void 110730554d9SArtem B. Bityutskiy jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 111730554d9SArtem B. Bityutskiy { 112730554d9SArtem B. Bityutskiy uint32_t my_used_size = 0; 113730554d9SArtem B. Bityutskiy uint32_t my_unchecked_size = 0; 114730554d9SArtem B. Bityutskiy uint32_t my_dirty_size = 0; 115730554d9SArtem B. Bityutskiy struct jffs2_raw_node_ref *ref2 = jeb->first_node; 116730554d9SArtem B. Bityutskiy 117730554d9SArtem B. Bityutskiy while (ref2) { 118730554d9SArtem B. Bityutskiy uint32_t totlen = ref_totlen(c, jeb, ref2); 119730554d9SArtem B. Bityutskiy 120730554d9SArtem B. Bityutskiy if (ref2->flash_offset < jeb->offset || 121730554d9SArtem B. Bityutskiy ref2->flash_offset > jeb->offset + c->sector_size) { 122730554d9SArtem B. Bityutskiy printk(KERN_ERR "node_ref %#08x shouldn't be in block at %#08x!\n", 123730554d9SArtem B. Bityutskiy ref_offset(ref2), jeb->offset); 124730554d9SArtem B. Bityutskiy jffs2_dbg_dump_node_refs(c, jeb); 125730554d9SArtem B. Bityutskiy jffs2_dbg_dump_block_lists(c); 126730554d9SArtem B. Bityutskiy BUG(); 127730554d9SArtem B. Bityutskiy 128730554d9SArtem B. Bityutskiy } 129730554d9SArtem B. Bityutskiy if (ref_flags(ref2) == REF_UNCHECKED) 130730554d9SArtem B. Bityutskiy my_unchecked_size += totlen; 131730554d9SArtem B. Bityutskiy else if (!ref_obsolete(ref2)) 132730554d9SArtem B. Bityutskiy my_used_size += totlen; 133730554d9SArtem B. Bityutskiy else 134730554d9SArtem B. Bityutskiy my_dirty_size += totlen; 135730554d9SArtem B. Bityutskiy 136730554d9SArtem B. Bityutskiy if ((!ref2->next_phys) != (ref2 == jeb->last_node)) { 137730554d9SArtem B. Bityutskiy printk(KERN_ERR "node_ref for node at %#08x (mem %p) has next_phys at %#08x (mem %p), " 138730554d9SArtem B. Bityutskiy "last_node is at %#08x (mem %p)\n", 139730554d9SArtem B. Bityutskiy ref_offset(ref2), ref2, ref_offset(ref2->next_phys), ref2->next_phys, 140730554d9SArtem B. Bityutskiy ref_offset(jeb->last_node), jeb->last_node); 141730554d9SArtem B. Bityutskiy jffs2_dbg_dump_node_refs(c, jeb); 142730554d9SArtem B. Bityutskiy jffs2_dbg_dump_block_lists(c); 143730554d9SArtem B. Bityutskiy BUG(); 144730554d9SArtem B. Bityutskiy } 145730554d9SArtem B. Bityutskiy ref2 = ref2->next_phys; 146730554d9SArtem B. Bityutskiy } 147730554d9SArtem B. Bityutskiy 148730554d9SArtem B. Bityutskiy if (my_used_size != jeb->used_size) { 149730554d9SArtem B. Bityutskiy printk(KERN_ERR "Calculated used size %#08x != stored used size %#08x\n", 150730554d9SArtem B. Bityutskiy my_used_size, jeb->used_size); 151730554d9SArtem B. Bityutskiy jffs2_dbg_dump_node_refs(c, jeb); 152730554d9SArtem B. Bityutskiy jffs2_dbg_dump_block_lists(c); 153730554d9SArtem B. Bityutskiy BUG(); 154730554d9SArtem B. Bityutskiy } 155730554d9SArtem B. Bityutskiy 156730554d9SArtem B. Bityutskiy if (my_unchecked_size != jeb->unchecked_size) { 157730554d9SArtem B. Bityutskiy printk(KERN_ERR "Calculated unchecked size %#08x != stored unchecked size %#08x\n", 158730554d9SArtem B. Bityutskiy my_unchecked_size, jeb->unchecked_size); 159730554d9SArtem B. Bityutskiy jffs2_dbg_dump_node_refs(c, jeb); 160730554d9SArtem B. Bityutskiy jffs2_dbg_dump_block_lists(c); 161730554d9SArtem B. Bityutskiy BUG(); 162730554d9SArtem B. Bityutskiy } 163730554d9SArtem B. Bityutskiy 164730554d9SArtem B. Bityutskiy if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) { 165730554d9SArtem B. Bityutskiy printk(KERN_ERR "Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n", 166730554d9SArtem B. Bityutskiy my_dirty_size, jeb->dirty_size + jeb->wasted_size); 167730554d9SArtem B. Bityutskiy jffs2_dbg_dump_node_refs(c, jeb); 168730554d9SArtem B. Bityutskiy jffs2_dbg_dump_block_lists(c); 169730554d9SArtem B. Bityutskiy BUG(); 170730554d9SArtem B. Bityutskiy } 171730554d9SArtem B. Bityutskiy 172730554d9SArtem B. Bityutskiy if (jeb->free_size == 0 173730554d9SArtem B. Bityutskiy && my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) { 174730554d9SArtem B. Bityutskiy printk(KERN_ERR "The sum of all nodes in block (%#x) != size of block (%#x)\n", 175730554d9SArtem B. Bityutskiy my_used_size + my_unchecked_size + my_dirty_size, 176730554d9SArtem B. Bityutskiy c->sector_size); 177730554d9SArtem B. Bityutskiy jffs2_dbg_dump_node_refs(c, jeb); 178730554d9SArtem B. Bityutskiy jffs2_dbg_dump_block_lists(c); 179730554d9SArtem B. Bityutskiy BUG(); 180730554d9SArtem B. Bityutskiy } 181730554d9SArtem B. Bityutskiy } 182730554d9SArtem B. Bityutskiy #endif /* JFFS2_PARANOIA_CHECKS */ 183730554d9SArtem B. Bityutskiy 184730554d9SArtem B. Bityutskiy #if defined(JFFS2_PARANOIA_CHECKS) || (CONFIG_JFFS2_FS_DEBUG > 0) 185730554d9SArtem B. Bityutskiy /* 186730554d9SArtem B. Bityutskiy * Dump the node_refs of the 'jeb' JFFS2 eraseblock. 187730554d9SArtem B. Bityutskiy */ 188730554d9SArtem B. Bityutskiy void 189730554d9SArtem B. Bityutskiy jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 190730554d9SArtem B. Bityutskiy { 191730554d9SArtem B. Bityutskiy struct jffs2_raw_node_ref *ref; 192730554d9SArtem B. Bityutskiy int i = 0; 193730554d9SArtem B. Bityutskiy 194730554d9SArtem B. Bityutskiy if (!jeb->first_node) { 195730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "no nodes in block %#08x\n", jeb->offset); 196730554d9SArtem B. Bityutskiy return; 197730554d9SArtem B. Bityutskiy } 198730554d9SArtem B. Bityutskiy 199730554d9SArtem B. Bityutskiy printk(KERN_DEBUG); 200730554d9SArtem B. Bityutskiy for (ref = jeb->first_node; ; ref = ref->next_phys) { 201730554d9SArtem B. Bityutskiy printk("%#08x(%#x)", ref_offset(ref), ref->__totlen); 202730554d9SArtem B. Bityutskiy if (ref->next_phys) 203730554d9SArtem B. Bityutskiy printk("->"); 204730554d9SArtem B. Bityutskiy else 205730554d9SArtem B. Bityutskiy break; 206730554d9SArtem B. Bityutskiy if (++i == 4) { 207730554d9SArtem B. Bityutskiy i = 0; 208730554d9SArtem B. Bityutskiy printk("\n" KERN_DEBUG); 209730554d9SArtem B. Bityutskiy } 210730554d9SArtem B. Bityutskiy } 211730554d9SArtem B. Bityutskiy printk("\n"); 212730554d9SArtem B. Bityutskiy } 213730554d9SArtem B. Bityutskiy 214730554d9SArtem B. Bityutskiy void 215730554d9SArtem B. Bityutskiy jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c) 216730554d9SArtem B. Bityutskiy { 217730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "flash_size: %#08x\n", c->flash_size); 218730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "used_size: %#08x\n", c->used_size); 219730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "dirty_size: %#08x\n", c->dirty_size); 220730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "wasted_size: %#08x\n", c->wasted_size); 221730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "unchecked_size: %#08x\n", c->unchecked_size); 222730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "free_size: %#08x\n", c->free_size); 223730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "erasing_size: %#08x\n", c->erasing_size); 224730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "bad_size: %#08x\n", c->bad_size); 225730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "sector_size: %#08x\n", c->sector_size); 226730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "jffs2_reserved_blocks size: %#08x\n", 227730554d9SArtem B. Bityutskiy c->sector_size * c->resv_blocks_write); 228730554d9SArtem B. Bityutskiy 229730554d9SArtem B. Bityutskiy if (c->nextblock) 230730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, " 231730554d9SArtem B. Bityutskiy "unchecked %#08x, free %#08x)\n", 232730554d9SArtem B. Bityutskiy c->nextblock->offset, c->nextblock->used_size, 233730554d9SArtem B. Bityutskiy c->nextblock->dirty_size, c->nextblock->wasted_size, 234730554d9SArtem B. Bityutskiy c->nextblock->unchecked_size, c->nextblock->free_size); 235730554d9SArtem B. Bityutskiy else 236730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "nextblock: NULL\n"); 237730554d9SArtem B. Bityutskiy 238730554d9SArtem B. Bityutskiy if (c->gcblock) 239730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, " 240730554d9SArtem B. Bityutskiy "unchecked %#08x, free %#08x)\n", 241730554d9SArtem B. Bityutskiy c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size, 242730554d9SArtem B. Bityutskiy c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size); 243730554d9SArtem B. Bityutskiy else 244730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "gcblock: NULL\n"); 245730554d9SArtem B. Bityutskiy 246730554d9SArtem B. Bityutskiy if (list_empty(&c->clean_list)) { 247730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "clean_list: empty\n"); 248730554d9SArtem B. Bityutskiy } else { 249730554d9SArtem B. Bityutskiy struct list_head *this; 250730554d9SArtem B. Bityutskiy int numblocks = 0; 251730554d9SArtem B. Bityutskiy uint32_t dirty = 0; 252730554d9SArtem B. Bityutskiy 253730554d9SArtem B. Bityutskiy list_for_each(this, &c->clean_list) { 254730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 255730554d9SArtem B. Bityutskiy numblocks ++; 256730554d9SArtem B. Bityutskiy dirty += jeb->wasted_size; 257730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 258730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " 259730554d9SArtem B. Bityutskiy "unchecked %#08x, free %#08x)\n", 260730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 261730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size); 262730554d9SArtem B. Bityutskiy } 263730554d9SArtem B. Bityutskiy } 264730554d9SArtem B. Bityutskiy 265730554d9SArtem B. Bityutskiy printk (KERN_DEBUG "Contains %d blocks with total wasted size %u, average wasted size: %u\n", 266730554d9SArtem B. Bityutskiy numblocks, dirty, dirty / numblocks); 267730554d9SArtem B. Bityutskiy } 268730554d9SArtem B. Bityutskiy 269730554d9SArtem B. Bityutskiy if (list_empty(&c->very_dirty_list)) { 270730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "very_dirty_list: empty\n"); 271730554d9SArtem B. Bityutskiy } else { 272730554d9SArtem B. Bityutskiy struct list_head *this; 273730554d9SArtem B. Bityutskiy int numblocks = 0; 274730554d9SArtem B. Bityutskiy uint32_t dirty = 0; 275730554d9SArtem B. Bityutskiy 276730554d9SArtem B. Bityutskiy list_for_each(this, &c->very_dirty_list) { 277730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 278730554d9SArtem B. Bityutskiy 279730554d9SArtem B. Bityutskiy numblocks ++; 280730554d9SArtem B. Bityutskiy dirty += jeb->dirty_size; 281730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 282730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " 283730554d9SArtem B. Bityutskiy "unchecked %#08x, free %#08x)\n", 284730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 285730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size); 286730554d9SArtem B. Bityutskiy } 287730554d9SArtem B. Bityutskiy } 288730554d9SArtem B. Bityutskiy 289730554d9SArtem B. Bityutskiy printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n", 290730554d9SArtem B. Bityutskiy numblocks, dirty, dirty / numblocks); 291730554d9SArtem B. Bityutskiy } 292730554d9SArtem B. Bityutskiy 293730554d9SArtem B. Bityutskiy if (list_empty(&c->dirty_list)) { 294730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "dirty_list: empty\n"); 295730554d9SArtem B. Bityutskiy } else { 296730554d9SArtem B. Bityutskiy struct list_head *this; 297730554d9SArtem B. Bityutskiy int numblocks = 0; 298730554d9SArtem B. Bityutskiy uint32_t dirty = 0; 299730554d9SArtem B. Bityutskiy 300730554d9SArtem B. Bityutskiy list_for_each(this, &c->dirty_list) { 301730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 302730554d9SArtem B. Bityutskiy 303730554d9SArtem B. Bityutskiy numblocks ++; 304730554d9SArtem B. Bityutskiy dirty += jeb->dirty_size; 305730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 306730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " 307730554d9SArtem B. Bityutskiy "unchecked %#08x, free %#08x)\n", 308730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 309730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size); 310730554d9SArtem B. Bityutskiy } 311730554d9SArtem B. Bityutskiy } 312730554d9SArtem B. Bityutskiy 313730554d9SArtem B. Bityutskiy printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n", 314730554d9SArtem B. Bityutskiy numblocks, dirty, dirty / numblocks); 315730554d9SArtem B. Bityutskiy } 316730554d9SArtem B. Bityutskiy 317730554d9SArtem B. Bityutskiy if (list_empty(&c->erasable_list)) { 318730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "erasable_list: empty\n"); 319730554d9SArtem B. Bityutskiy } else { 320730554d9SArtem B. Bityutskiy struct list_head *this; 321730554d9SArtem B. Bityutskiy 322730554d9SArtem B. Bityutskiy list_for_each(this, &c->erasable_list) { 323730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 324730554d9SArtem B. Bityutskiy 325730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 326730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " 327730554d9SArtem B. Bityutskiy "unchecked %#08x, free %#08x)\n", 328730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 329730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size); 330730554d9SArtem B. Bityutskiy } 331730554d9SArtem B. Bityutskiy } 332730554d9SArtem B. Bityutskiy } 333730554d9SArtem B. Bityutskiy 334730554d9SArtem B. Bityutskiy if (list_empty(&c->erasing_list)) { 335730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "erasing_list: empty\n"); 336730554d9SArtem B. Bityutskiy } else { 337730554d9SArtem B. Bityutskiy struct list_head *this; 338730554d9SArtem B. Bityutskiy 339730554d9SArtem B. Bityutskiy list_for_each(this, &c->erasing_list) { 340730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 341730554d9SArtem B. Bityutskiy 342730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 343730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " 344730554d9SArtem B. Bityutskiy "unchecked %#08x, free %#08x)\n", 345730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 346730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size); 347730554d9SArtem B. Bityutskiy } 348730554d9SArtem B. Bityutskiy } 349730554d9SArtem B. Bityutskiy } 350730554d9SArtem B. Bityutskiy 351730554d9SArtem B. Bityutskiy if (list_empty(&c->erase_pending_list)) { 352730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "erase_pending_list: empty\n"); 353730554d9SArtem B. Bityutskiy } else { 354730554d9SArtem B. Bityutskiy struct list_head *this; 355730554d9SArtem B. Bityutskiy 356730554d9SArtem B. Bityutskiy list_for_each(this, &c->erase_pending_list) { 357730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 358730554d9SArtem B. Bityutskiy 359730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 360730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " 361730554d9SArtem B. Bityutskiy "unchecked %#08x, free %#08x)\n", 362730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 363730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size); 364730554d9SArtem B. Bityutskiy } 365730554d9SArtem B. Bityutskiy } 366730554d9SArtem B. Bityutskiy } 367730554d9SArtem B. Bityutskiy 368730554d9SArtem B. Bityutskiy if (list_empty(&c->erasable_pending_wbuf_list)) { 369730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "erasable_pending_wbuf_list: empty\n"); 370730554d9SArtem B. Bityutskiy } else { 371730554d9SArtem B. Bityutskiy struct list_head *this; 372730554d9SArtem B. Bityutskiy 373730554d9SArtem B. Bityutskiy list_for_each(this, &c->erasable_pending_wbuf_list) { 374730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 375730554d9SArtem B. Bityutskiy 376730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 377730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, " 378730554d9SArtem B. Bityutskiy "wasted %#08x, unchecked %#08x, free %#08x)\n", 379730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 380730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size); 381730554d9SArtem B. Bityutskiy } 382730554d9SArtem B. Bityutskiy } 383730554d9SArtem B. Bityutskiy } 384730554d9SArtem B. Bityutskiy 385730554d9SArtem B. Bityutskiy if (list_empty(&c->free_list)) { 386730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "free_list: empty\n"); 387730554d9SArtem B. Bityutskiy } else { 388730554d9SArtem B. Bityutskiy struct list_head *this; 389730554d9SArtem B. Bityutskiy 390730554d9SArtem B. Bityutskiy list_for_each(this, &c->free_list) { 391730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 392730554d9SArtem B. Bityutskiy 393730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 394730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " 395730554d9SArtem B. Bityutskiy "unchecked %#08x, free %#08x)\n", 396730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 397730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size); 398730554d9SArtem B. Bityutskiy } 399730554d9SArtem B. Bityutskiy } 400730554d9SArtem B. Bityutskiy } 401730554d9SArtem B. Bityutskiy 402730554d9SArtem B. Bityutskiy if (list_empty(&c->bad_list)) { 403730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "bad_list: empty\n"); 404730554d9SArtem B. Bityutskiy } else { 405730554d9SArtem B. Bityutskiy struct list_head *this; 406730554d9SArtem B. Bityutskiy 407730554d9SArtem B. Bityutskiy list_for_each(this, &c->bad_list) { 408730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 409730554d9SArtem B. Bityutskiy 410730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 411730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " 412730554d9SArtem B. Bityutskiy "unchecked %#08x, free %#08x)\n", 413730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 414730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size); 415730554d9SArtem B. Bityutskiy } 416730554d9SArtem B. Bityutskiy } 417730554d9SArtem B. Bityutskiy } 418730554d9SArtem B. Bityutskiy 419730554d9SArtem B. Bityutskiy if (list_empty(&c->bad_used_list)) { 420730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "bad_used_list: empty\n"); 421730554d9SArtem B. Bityutskiy } else { 422730554d9SArtem B. Bityutskiy struct list_head *this; 423730554d9SArtem B. Bityutskiy 424730554d9SArtem B. Bityutskiy list_for_each(this, &c->bad_used_list) { 425730554d9SArtem B. Bityutskiy struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); 426730554d9SArtem B. Bityutskiy 427730554d9SArtem B. Bityutskiy if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { 428730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " 429730554d9SArtem B. Bityutskiy "unchecked %#08x, free %#08x)\n", 430730554d9SArtem B. Bityutskiy jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, 431730554d9SArtem B. Bityutskiy jeb->unchecked_size, jeb->free_size); 432730554d9SArtem B. Bityutskiy } 433730554d9SArtem B. Bityutskiy } 434730554d9SArtem B. Bityutskiy } 435730554d9SArtem B. Bityutskiy } 436730554d9SArtem B. Bityutskiy 437730554d9SArtem B. Bityutskiy void 438730554d9SArtem B. Bityutskiy jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f) 439730554d9SArtem B. Bityutskiy { 440730554d9SArtem B. Bityutskiy struct jffs2_node_frag *this = frag_first(&f->fragtree); 441730554d9SArtem B. Bityutskiy uint32_t lastofs = 0; 442730554d9SArtem B. Bityutskiy int buggy = 0; 443730554d9SArtem B. Bityutskiy 444730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "inode is ino #%u\n", f->inocache->ino); 445730554d9SArtem B. Bityutskiy while(this) { 446730554d9SArtem B. Bityutskiy if (this->node) 447730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "frag %#04x-%#04x: %#08x(%d) on flash (*%p), left (%p), " 448730554d9SArtem B. Bityutskiy "right (%p), parent (%p)\n", 449730554d9SArtem B. Bityutskiy this->ofs, this->ofs+this->size, ref_offset(this->node->raw), 450730554d9SArtem B. Bityutskiy ref_flags(this->node->raw), this, frag_left(this), frag_right(this), 451730554d9SArtem B. Bityutskiy frag_parent(this)); 452730554d9SArtem B. Bityutskiy else 453730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n", 454730554d9SArtem B. Bityutskiy this->ofs, this->ofs+this->size, this, frag_left(this), 455730554d9SArtem B. Bityutskiy frag_right(this), frag_parent(this)); 456730554d9SArtem B. Bityutskiy if (this->ofs != lastofs) 457730554d9SArtem B. Bityutskiy buggy = 1; 458730554d9SArtem B. Bityutskiy lastofs = this->ofs + this->size; 459730554d9SArtem B. Bityutskiy this = frag_next(this); 460730554d9SArtem B. Bityutskiy } 461730554d9SArtem B. Bityutskiy 462730554d9SArtem B. Bityutskiy if (f->metadata) 463730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "metadata at 0x%08x\n", ref_offset(f->metadata->raw)); 464730554d9SArtem B. Bityutskiy 465730554d9SArtem B. Bityutskiy if (buggy) { 466730554d9SArtem B. Bityutskiy printk(KERN_ERR "Error! %s(): Frag tree got a hole in it\n", __FUNCTION__); 467730554d9SArtem B. Bityutskiy BUG(); 468730554d9SArtem B. Bityutskiy } 469730554d9SArtem B. Bityutskiy } 470730554d9SArtem B. Bityutskiy 471730554d9SArtem B. Bityutskiy #define JFFS3_BUFDUMP_BYTES_PER_LINE 8 472730554d9SArtem B. Bityutskiy void 473730554d9SArtem B. Bityutskiy jffs2_dbg_dump_buffer(char *buf, int len, uint32_t offs) 474730554d9SArtem B. Bityutskiy { 475730554d9SArtem B. Bityutskiy int i = 0; 476730554d9SArtem B. Bityutskiy int skip = offs & ~(JFFS3_BUFDUMP_BYTES_PER_LINE - 1); 477730554d9SArtem B. Bityutskiy 478730554d9SArtem B. Bityutskiy while (i < len) { 479730554d9SArtem B. Bityutskiy int j = 0; 480730554d9SArtem B. Bityutskiy 481730554d9SArtem B. Bityutskiy printk(KERN_DEBUG "0x#x: \n"); 482730554d9SArtem B. Bityutskiy while (skip) { 483730554d9SArtem B. Bityutskiy printk(" "); 484730554d9SArtem B. Bityutskiy skip -= 1; 485730554d9SArtem B. Bityutskiy } 486730554d9SArtem B. Bityutskiy 487730554d9SArtem B. Bityutskiy while (j < JFFS3_BUFDUMP_BYTES_PER_LINE) { 488730554d9SArtem B. Bityutskiy if (i + j < len) 489730554d9SArtem B. Bityutskiy printk(" %#02x", buf[i + j++]); 490730554d9SArtem B. Bityutskiy } 491730554d9SArtem B. Bityutskiy 492730554d9SArtem B. Bityutskiy i += JFFS3_BUFDUMP_BYTES_PER_LINE; 493730554d9SArtem B. Bityutskiy } 494730554d9SArtem B. Bityutskiy } 495730554d9SArtem B. Bityutskiy #endif /* JFFS2_PARANOIA_CHECKS || CONFIG_JFFS2_FS_DEBUG > 0 */ 496