uint32_t alloclen, phys_ofs; 
uint32_t alloclen, phys_ofs, ilen; 
static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,				      struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,				      uint32_t start, uint32_t end){	struct jffs2_raw_inode ri;	struct jffs2_node_frag *frag;	struct jffs2_full_dnode *new_fn;	uint32_t alloclen, phys_ofs;	int ret;	D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n",		  f->inocache->ino, start, end));		memset(&ri, 0, sizeof(ri));	if(fn->frags > 1) {		size_t readlen;		uint32_t crc;		/* It's partially obsoleted by a later write. So we have to 		   write it out again with the _same_ version as before */		ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(ri), &readlen, (char *)&ri);		if (readlen != sizeof(ri) || ret) {			printk(KERN_WARNING "Node read failed in jffs2_garbage_collect_hole. Ret %d, retlen %zd. Data will be lost by writing new hole node\n", ret, readlen);			goto fill;		}		if (je16_to_cpu(ri.nodetype) != JFFS2_NODETYPE_INODE) {			printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had node type 0x%04x instead of JFFS2_NODETYPE_INODE(0x%04x)\n",			       ref_offset(fn->raw),			       je16_to_cpu(ri.nodetype), JFFS2_NODETYPE_INODE);			return -EIO;		}		if (je32_to_cpu(ri.totlen) != sizeof(ri)) {			printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had totlen 0x%x instead of expected 0x%zx\n",			       ref_offset(fn->raw),			       je32_to_cpu(ri.totlen), sizeof(ri));			return -EIO;		}		crc = crc32(0, &ri, sizeof(ri)-8);		if (crc != je32_to_cpu(ri.node_crc)) {			printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n",			       ref_offset(fn->raw), 			       je32_to_cpu(ri.node_crc), crc);			/* FIXME: We could possibly deal with this by writing new holes for each frag */			printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", 			       start, end, f->inocache->ino);			goto fill;		}		if (ri.compr != JFFS2_COMPR_ZERO) {			printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", ref_offset(fn->raw));			printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", 			       start, end, f->inocache->ino);			goto fill;		}	} else {	fill:		ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);		ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);		ri.totlen = cpu_to_je32(sizeof(ri));		ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4));		ri.ino = cpu_to_je32(f->inocache->ino);		ri.version = cpu_to_je32(++f->highest_version);		ri.offset = cpu_to_je32(start);		ri.dsize = cpu_to_je32(end - start);		ri.csize = cpu_to_je32(0);		ri.compr = JFFS2_COMPR_ZERO;	}	ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));	ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));	ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));	ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f));	ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));	ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));	ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));	ri.data_crc = cpu_to_je32(0);	ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));	ret = jffs2_reserve_space_gc(c, sizeof(ri), &phys_ofs, &alloclen);	if (ret) {		printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_hole failed: %d\n",		       sizeof(ri), ret);		return ret;	}	new_fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_GC);	if (IS_ERR(new_fn)) {		printk(KERN_WARNING "Error writing new hole node: %ld\n", PTR_ERR(new_fn));		return PTR_ERR(new_fn);	}	if (je32_to_cpu(ri.version) == f->highest_version) {		jffs2_add_full_dnode_to_inode(c, f, new_fn);		if (f->metadata) {			jffs2_mark_node_obsolete(c, f->metadata->raw);			jffs2_free_full_dnode(f->metadata);			f->metadata = NULL;		}		return 0;	}	/* 	 * We should only get here in the case where the node we are	 * replacing had more than one frag, so we kept the same version	 * number as before. (Except in case of error -- see 'goto fill;' 	 * above.)	 */	D1(if(unlikely(fn->frags <= 1)) {		printk(KERN_WARNING "jffs2_garbage_collect_hole: Replacing fn with %d frag(s) but new ver %d != highest_version %d of ino #%d\n",		       fn->frags, je32_to_cpu(ri.version), f->highest_version,		       je32_to_cpu(ri.ino));	});	/* This is a partially-overlapped hole node. Mark it REF_NORMAL not REF_PRISTINE */	mark_ref_normal(new_fn->raw);	for (frag = jffs2_lookup_node_frag(&f->fragtree, fn->ofs); 	     frag; frag = frag_next(frag)) {		if (frag->ofs > fn->size + fn->ofs)			break;		if (frag->node == fn) {			frag->node = new_fn;			new_fn->frags++;			fn->frags--;		}	}	if (fn->frags) {		printk(KERN_WARNING "jffs2_garbage_collect_hole: Old node still has frags!\n");		BUG();	}	if (!new_fn->frags) {		printk(KERN_WARNING "jffs2_garbage_collect_hole: New node has no frags!\n");		BUG();	}			jffs2_mark_node_obsolete(c, fn->raw);	jffs2_free_full_dnode(fn);		return 0;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/8557fd51c22e4c2109f062decd19de439061ceae/gc.c/buggy/fs/jffs2/gc.c