uint32_t skip = c->nextblock->free_size & (c->wbuf_pagesize-1); 
uint32_t skip = c->nextblock->free_size % c->wbuf_pagesize; 
int jffs2_scan_medium(struct jffs2_sb_info *c){	int i, ret;	uint32_t empty_blocks = 0, bad_blocks = 0;	unsigned char *flashbuf = NULL;	uint32_t buf_size = 0;	struct jffs2_summary *s = NULL; /* summary info collected by the scan process */#ifndef __ECOS	size_t pointlen;	if (c->mtd->point) {		ret = c->mtd->point (c->mtd, 0, c->mtd->size, &pointlen, &flashbuf);		if (!ret && pointlen < c->mtd->size) {			/* Don't muck about if it won't let us point to the whole flash */			D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen));			c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);			flashbuf = NULL;		}		if (ret)			D1(printk(KERN_DEBUG "MTD point failed %d\n", ret));	}#endif	if (!flashbuf) {		/* For NAND it's quicker to read a whole eraseblock at a time,		   apparently */		if (jffs2_cleanmarker_oob(c))			buf_size = c->sector_size;		else			buf_size = PAGE_SIZE;		/* Respect kmalloc limitations */		if (buf_size > 128*1024)			buf_size = 128*1024;		D1(printk(KERN_DEBUG "Allocating readbuf of %d bytes\n", buf_size));		flashbuf = kmalloc(buf_size, GFP_KERNEL);		if (!flashbuf)			return -ENOMEM;	}	if (jffs2_sum_active()) {		s = kmalloc(sizeof(struct jffs2_summary), GFP_KERNEL);		if (!s) {			JFFS2_WARNING("Can't allocate memory for summary\n");			return -ENOMEM;		}		memset(s, 0, sizeof(struct jffs2_summary));	}	for (i=0; i<c->nr_blocks; i++) {		struct jffs2_eraseblock *jeb = &c->blocks[i];		/* reset summary info for next eraseblock scan */		jffs2_sum_reset_collected(s);		ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),						buf_size, s);		if (ret < 0)			goto out;		jffs2_dbg_acct_paranoia_check_nolock(c, jeb);		/* Now decide which list to put it on */		switch(ret) {		case BLK_STATE_ALLFF:			/* 			 * Empty block.   Since we can't be sure it 			 * was entirely erased, we just queue it for erase			 * again.  It will be marked as such when the erase			 * is complete.  Meanwhile we still count it as empty			 * for later checks.			 */			empty_blocks++;			list_add(&jeb->list, &c->erase_pending_list);			c->nr_erasing_blocks++;			break;		case BLK_STATE_CLEANMARKER:			/* Only a CLEANMARKER node is valid */			if (!jeb->dirty_size) {				/* It's actually free */				list_add(&jeb->list, &c->free_list);				c->nr_free_blocks++;			} else {				/* Dirt */				D1(printk(KERN_DEBUG "Adding all-dirty block at 0x%08x to erase_pending_list\n", jeb->offset));				list_add(&jeb->list, &c->erase_pending_list);				c->nr_erasing_blocks++;			}			break;		case BLK_STATE_CLEAN:			/* Full (or almost full) of clean data. Clean list */			list_add(&jeb->list, &c->clean_list);			break;		case BLK_STATE_PARTDIRTY:			/* Some data, but not full. Dirty list. */			/* We want to remember the block with most free space			and stick it in the 'nextblock' position to start writing to it. */			if (jeb->free_size > min_free(c) &&					(!c->nextblock || c->nextblock->free_size < jeb->free_size)) {				/* Better candidate for the next writes to go to */				if (c->nextblock) {					c->nextblock->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;					c->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;					c->free_size -= c->nextblock->free_size;					c->wasted_size -= c->nextblock->wasted_size;					c->nextblock->free_size = c->nextblock->wasted_size = 0;					if (VERYDIRTY(c, c->nextblock->dirty_size)) {						list_add(&c->nextblock->list, &c->very_dirty_list);					} else {						list_add(&c->nextblock->list, &c->dirty_list);					}					/* deleting summary information of the old nextblock */					jffs2_sum_reset_collected(c->summary);				}				/* update collected summary infromation for the current nextblock */				jffs2_sum_move_collected(c, s);				D1(printk(KERN_DEBUG "jffs2_scan_medium(): new nextblock = 0x%08x\n", jeb->offset));				c->nextblock = jeb;			} else {				jeb->dirty_size += jeb->free_size + jeb->wasted_size;				c->dirty_size += jeb->free_size + jeb->wasted_size;				c->free_size -= jeb->free_size;				c->wasted_size -= jeb->wasted_size;				jeb->free_size = jeb->wasted_size = 0;				if (VERYDIRTY(c, jeb->dirty_size)) {					list_add(&jeb->list, &c->very_dirty_list);				} else {					list_add(&jeb->list, &c->dirty_list);				}			}			break;		case BLK_STATE_ALLDIRTY:			/* Nothing valid - not even a clean marker. Needs erasing. */			/* For now we just put it on the erasing list. We'll start the erases later */			D1(printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset));			list_add(&jeb->list, &c->erase_pending_list);			c->nr_erasing_blocks++;			break;		case BLK_STATE_BADBLOCK:			D1(printk(KERN_NOTICE "JFFS2: Block at 0x%08x is bad\n", jeb->offset));			list_add(&jeb->list, &c->bad_list);			c->bad_size += c->sector_size;			c->free_size -= c->sector_size;			bad_blocks++;			break;		default:			printk(KERN_WARNING "jffs2_scan_medium(): unknown block state\n");			BUG();		}	}	if (jffs2_sum_active() && s)		kfree(s);	/* Nextblock dirty is always seen as wasted, because we cannot recycle it now */	if (c->nextblock && (c->nextblock->dirty_size)) {		c->nextblock->wasted_size += c->nextblock->dirty_size;		c->wasted_size += c->nextblock->dirty_size;		c->dirty_size -= c->nextblock->dirty_size;		c->nextblock->dirty_size = 0;	}#ifdef CONFIG_JFFS2_FS_WRITEBUFFER	if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) {		/* If we're going to start writing into a block which already 		   contains data, and the end of the data isn't page-aligned,		   skip a little and align it. */		uint32_t skip = c->nextblock->free_size & (c->wbuf_pagesize-1);		D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n",			  skip));		c->nextblock->wasted_size += skip;		c->wasted_size += skip;		c->nextblock->free_size -= skip;		c->free_size -= skip;	}#endif	if (c->nr_erasing_blocks) {		if ( !c->used_size && ((c->nr_free_blocks+empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) { 			printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");			printk(KERN_NOTICE "empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n",empty_blocks,bad_blocks,c->nr_blocks);			ret = -EIO;			goto out;		}		jffs2_erase_pending_trigger(c);	}	ret = 0; out:	if (buf_size)		kfree(flashbuf);#ifndef __ECOS	else 		c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);#endif	return ret;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/daba5cc4bcd025a9b4fd02a9117c71bfd400d811/scan.c/clean/fs/jffs2/scan.c