JFFS2_DBG_SUMMARY("no summary found in jeb 0x%08x. Apply original scan.\n",jeb->offset); 
dbg_summary("no summary found in jeb 0x%08x. Apply original scan.\n",jeb->offset); 
static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,				unsigned char *buf, uint32_t buf_size, struct jffs2_summary *s) {	struct jffs2_unknown_node *node;	struct jffs2_unknown_node crcnode;	struct jffs2_sum_marker *sm;	uint32_t ofs, prevofs;	uint32_t hdr_crc, buf_ofs, buf_len;	int err;	int noise = 0;#ifdef CONFIG_JFFS2_FS_WRITEBUFFER	int cleanmarkerfound = 0;#endif	ofs = jeb->offset;	prevofs = jeb->offset - 1;	D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs));#ifdef CONFIG_JFFS2_FS_WRITEBUFFER	if (jffs2_cleanmarker_oob(c)) {		int ret = jffs2_check_nand_cleanmarker(c, jeb);		D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret));		/* Even if it's not found, we still scan to see		   if the block is empty. We use this information		   to decide whether to erase it or not. */		switch (ret) {		case 0:		cleanmarkerfound = 1; break;		case 1: 	break;		case 2: 	return BLK_STATE_BADBLOCK;		case 3:		return BLK_STATE_ALLDIRTY; /* Block has failed to erase min. once */		default: 	return ret;		}	}#endif	if (jffs2_sum_active()) {		sm = kmalloc(sizeof(struct jffs2_sum_marker), GFP_KERNEL);		if (!sm) {			return -ENOMEM;		}		err = jffs2_fill_scan_buf(c, (unsigned char *) sm, jeb->offset + c->sector_size -					sizeof(struct jffs2_sum_marker), sizeof(struct jffs2_sum_marker));		if (err) {			kfree(sm);			return err;		}		if (je32_to_cpu(sm->magic) == JFFS2_SUM_MAGIC ) {			err = jffs2_sum_scan_sumnode(c, jeb, je32_to_cpu(sm->offset), &pseudo_random);			if (err) {				kfree(sm);				return err;			}		}		kfree(sm);		ofs = jeb->offset;		prevofs = jeb->offset - 1;	}	buf_ofs = jeb->offset;	if (!buf_size) {		buf_len = c->sector_size;		if (jffs2_sum_active()) {			/* must reread because of summary test */			err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);			if (err)				return err;		}	} else {		buf_len = EMPTY_SCAN_SIZE(c->sector_size);		err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);		if (err)			return err;	}		/* We temporarily use 'ofs' as a pointer into the buffer/jeb */	ofs = 0;	/* Scan only 4KiB of 0xFF before declaring it's empty */	while(ofs < EMPTY_SCAN_SIZE(c->sector_size) && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF)		ofs += 4;	if (ofs == EMPTY_SCAN_SIZE(c->sector_size)) {#ifdef CONFIG_JFFS2_FS_WRITEBUFFER		if (jffs2_cleanmarker_oob(c)) {			/* scan oob, take care of cleanmarker */			int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound);			D2(printk(KERN_NOTICE "jffs2_check_oob_empty returned %d\n",ret));			switch (ret) {			case 0:		return cleanmarkerfound ? BLK_STATE_CLEANMARKER : BLK_STATE_ALLFF;			case 1: 	return BLK_STATE_ALLDIRTY;			default: 	return ret;			}		}#endif		D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset));		if (c->cleanmarker_size == 0)			return BLK_STATE_CLEANMARKER;	/* don't bother with re-erase */		else			return BLK_STATE_ALLFF;	/* OK to erase if all blocks are like this */	}	if (ofs) {		D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset,			  jeb->offset + ofs));		DIRTY_SPACE(ofs);	}	/* Now ofs is a complete physical flash offset as it always was... */	ofs += jeb->offset;	noise = 10;	JFFS2_DBG_SUMMARY("no summary found in jeb 0x%08x. Apply original scan.\n",jeb->offset);scan_more:		while(ofs < jeb->offset + c->sector_size) {		jffs2_dbg_acct_paranoia_check_nolock(c, jeb);		cond_resched();		if (ofs & 3) {			printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs);			ofs = PAD(ofs);			continue;		}		if (ofs == prevofs) {			printk(KERN_WARNING "ofs 0x%08x has already been seen. Skipping\n", ofs);			DIRTY_SPACE(4);			ofs += 4;			continue;		}		prevofs = ofs;		if (jeb->offset + c->sector_size < ofs + sizeof(*node)) {			D1(printk(KERN_DEBUG "Fewer than %zd bytes left to end of block. (%x+%x<%x+%zx) Not reading\n", sizeof(struct jffs2_unknown_node),				  jeb->offset, c->sector_size, ofs, sizeof(*node)));			DIRTY_SPACE((jeb->offset + c->sector_size)-ofs);			break;		}		if (buf_ofs + buf_len < ofs + sizeof(*node)) {			buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);			D1(printk(KERN_DEBUG "Fewer than %zd bytes (node header) left to end of buf. Reading 0x%x at 0x%08x\n",				  sizeof(struct jffs2_unknown_node), buf_len, ofs));			err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);			if (err)				return err;			buf_ofs = ofs;		}		node = (struct jffs2_unknown_node *)&buf[ofs-buf_ofs];		if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) {			uint32_t inbuf_ofs;			uint32_t empty_start;			empty_start = ofs;			ofs += 4;			D1(printk(KERN_DEBUG "Found empty flash at 0x%08x\n", ofs));		more_empty:			inbuf_ofs = ofs - buf_ofs;			while (inbuf_ofs < buf_len) {				if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff) {					printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n",					       empty_start, ofs);					DIRTY_SPACE(ofs-empty_start);					goto scan_more;				}				inbuf_ofs+=4;				ofs += 4;			}			/* Ran off end. */			D1(printk(KERN_DEBUG "Empty flash to end of buffer at 0x%08x\n", ofs));			/* If we're only checking the beginning of a block with a cleanmarker,			   bail now */			if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && 			    c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_phys) {				D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size)));				return BLK_STATE_CLEANMARKER;			}			/* See how much more there is to read in this eraseblock... */			buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);			if (!buf_len) {				/* No more to read. Break out of main loop without marking 				   this range of empty space as dirty (because it's not) */				D1(printk(KERN_DEBUG "Empty flash at %08x runs to end of block. Treating as free_space\n",					  empty_start));				break;			}			D1(printk(KERN_DEBUG "Reading another 0x%x at 0x%08x\n", buf_len, ofs));			err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);			if (err)				return err;			buf_ofs = ofs;			goto more_empty;		}		if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) {			printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs);			DIRTY_SPACE(4);			ofs += 4;			continue;		}		if (je16_to_cpu(node->magic) == JFFS2_DIRTY_BITMASK) {			D1(printk(KERN_DEBUG "Dirty bitmask at 0x%08x\n", ofs));			DIRTY_SPACE(4);			ofs += 4;			continue;		}		if (je16_to_cpu(node->magic) == JFFS2_OLD_MAGIC_BITMASK) {			printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs);			printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n");			DIRTY_SPACE(4);			ofs += 4;			continue;		}		if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) {			/* OK. We're out of possibilities. Whinge and move on */			noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", 				     JFFS2_MAGIC_BITMASK, ofs, 				     je16_to_cpu(node->magic));			DIRTY_SPACE(4);			ofs += 4;			continue;		}		/* We seem to have a node of sorts. Check the CRC */		crcnode.magic = node->magic;		crcnode.nodetype = cpu_to_je16( je16_to_cpu(node->nodetype) | JFFS2_NODE_ACCURATE);		crcnode.totlen = node->totlen;		hdr_crc = crc32(0, &crcnode, sizeof(crcnode)-4);		if (hdr_crc != je32_to_cpu(node->hdr_crc)) {			noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n",				     ofs, je16_to_cpu(node->magic),				     je16_to_cpu(node->nodetype), 				     je32_to_cpu(node->totlen),				     je32_to_cpu(node->hdr_crc),				     hdr_crc);			DIRTY_SPACE(4);			ofs += 4;			continue;		}		if (ofs + je32_to_cpu(node->totlen) > 		    jeb->offset + c->sector_size) {			/* Eep. Node goes over the end of the erase block. */			printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n",			       ofs, je32_to_cpu(node->totlen));			printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n");			DIRTY_SPACE(4);			ofs += 4;			continue;		}		if (!(je16_to_cpu(node->nodetype) & JFFS2_NODE_ACCURATE)) {			/* Wheee. This is an obsoleted node */			D2(printk(KERN_DEBUG "Node at 0x%08x is obsolete. Skipping\n", ofs));			DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));			ofs += PAD(je32_to_cpu(node->totlen));			continue;		}		switch(je16_to_cpu(node->nodetype)) {		case JFFS2_NODETYPE_INODE:			if (buf_ofs + buf_len < ofs + sizeof(struct jffs2_raw_inode)) {				buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);				D1(printk(KERN_DEBUG "Fewer than %zd bytes (inode node) left to end of buf. Reading 0x%x at 0x%08x\n",					  sizeof(struct jffs2_raw_inode), buf_len, ofs));				err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);				if (err)					return err;				buf_ofs = ofs;				node = (void *)buf;			}			err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs, s);			if (err) return err;			ofs += PAD(je32_to_cpu(node->totlen));			break;					case JFFS2_NODETYPE_DIRENT:			if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) {				buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);				D1(printk(KERN_DEBUG "Fewer than %d bytes (dirent node) left to end of buf. Reading 0x%x at 0x%08x\n",					  je32_to_cpu(node->totlen), buf_len, ofs));				err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);				if (err)					return err;				buf_ofs = ofs;				node = (void *)buf;			}			err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs, s);			if (err) return err;			ofs += PAD(je32_to_cpu(node->totlen));			break;		case JFFS2_NODETYPE_CLEANMARKER:			D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs));			if (je32_to_cpu(node->totlen) != c->cleanmarker_size) {				printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n", 				       ofs, je32_to_cpu(node->totlen), c->cleanmarker_size);				DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));				ofs += PAD(sizeof(struct jffs2_unknown_node));			} else if (jeb->first_node) {				printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", ofs, jeb->offset);				DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));				ofs += PAD(sizeof(struct jffs2_unknown_node));			} else {				struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref();				if (!marker_ref) {					printk(KERN_NOTICE "Failed to allocate node ref for clean marker\n");					return -ENOMEM;				}				marker_ref->next_in_ino = NULL;				marker_ref->next_phys = NULL;				marker_ref->flash_offset = ofs | REF_NORMAL;				marker_ref->__totlen = c->cleanmarker_size;				jeb->first_node = jeb->last_node = marker_ref;			     				USED_SPACE(PAD(c->cleanmarker_size));				ofs += PAD(c->cleanmarker_size);			}			break;		case JFFS2_NODETYPE_PADDING:			if (jffs2_sum_active())				jffs2_sum_add_padding_mem(s, je32_to_cpu(node->totlen));			DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));			ofs += PAD(je32_to_cpu(node->totlen));			break;		default:			switch (je16_to_cpu(node->nodetype) & JFFS2_COMPAT_MASK) {			case JFFS2_FEATURE_ROCOMPAT:				printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs);			        c->flags |= JFFS2_SB_FLAG_RO;				if (!(jffs2_is_readonly(c)))					return -EROFS;				DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));				ofs += PAD(je32_to_cpu(node->totlen));				break;			case JFFS2_FEATURE_INCOMPAT:				printk(KERN_NOTICE "Incompatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs);				return -EINVAL;			case JFFS2_FEATURE_RWCOMPAT_DELETE:				D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs));				DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));				ofs += PAD(je32_to_cpu(node->totlen));				break;			case JFFS2_FEATURE_RWCOMPAT_COPY:				D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs));				USED_SPACE(PAD(je32_to_cpu(node->totlen)));				ofs += PAD(je32_to_cpu(node->totlen));				break;			}		}	}	if (jffs2_sum_active()) {		if (PAD(s->sum_size + JFFS2_SUMMARY_FRAME_SIZE) > jeb->free_size) {			JFFS2_DBG_SUMMARY("There is not enough space for "				"summary information, disabling for this jeb!\n");			jffs2_sum_disable_collecting(s);		}	}	D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset, 		  jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size));	/* mark_node_obsolete can add to wasted !! */	if (jeb->wasted_size) {		jeb->dirty_size += jeb->wasted_size;		c->dirty_size += jeb->wasted_size;		c->wasted_size -= jeb->wasted_size;		jeb->wasted_size = 0;	}	return jffs2_scan_classify_jeb(c, jeb);}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/733802d974e5af42acb7cd61b16c0ce6dd03b7ed/scan.c/clean/fs/jffs2/scan.c