if (buf) kfree(buf); 
kfree(buf); 
static void jffs2_wbuf_recover(struct jffs2_sb_info *c){	struct jffs2_eraseblock *jeb, *new_jeb;	struct jffs2_raw_node_ref **first_raw, **raw;	size_t retlen;	int ret;	unsigned char *buf;	uint32_t start, end, ofs, len;	spin_lock(&c->erase_completion_lock);	jeb = &c->blocks[c->wbuf_ofs / c->sector_size];	jffs2_block_refile(c, jeb, REFILE_NOTEMPTY);	/* Find the first node to be recovered, by skipping over every	   node which ends before the wbuf starts, or which is obsolete. */	first_raw = &jeb->first_node;	while (*first_raw && 	       (ref_obsolete(*first_raw) ||		(ref_offset(*first_raw)+ref_totlen(c, jeb, *first_raw)) < c->wbuf_ofs)) {		D1(printk(KERN_DEBUG "Skipping node at 0x%08x(%d)-0x%08x which is either before 0x%08x or obsolete\n",			  ref_offset(*first_raw), ref_flags(*first_raw),			  (ref_offset(*first_raw) + ref_totlen(c, jeb, *first_raw)),			  c->wbuf_ofs));		first_raw = &(*first_raw)->next_phys;	}	if (!*first_raw) {		/* All nodes were obsolete. Nothing to recover. */		D1(printk(KERN_DEBUG "No non-obsolete nodes to be recovered. Just filing block bad\n"));		spin_unlock(&c->erase_completion_lock);		return;	}	start = ref_offset(*first_raw);	end = ref_offset(*first_raw) + ref_totlen(c, jeb, *first_raw);	/* Find the last node to be recovered */	raw = first_raw;	while ((*raw)) {		if (!ref_obsolete(*raw))			end = ref_offset(*raw) + ref_totlen(c, jeb, *raw);		raw = &(*raw)->next_phys;	}	spin_unlock(&c->erase_completion_lock);	D1(printk(KERN_DEBUG "wbuf recover %08x-%08x\n", start, end));	buf = NULL;	if (start < c->wbuf_ofs) {		/* First affected node was already partially written.		 * Attempt to reread the old data into our buffer. */		buf = kmalloc(end - start, GFP_KERNEL);		if (!buf) {			printk(KERN_CRIT "Malloc failure in wbuf recovery. Data loss ensues.\n");			goto read_failed;		}		/* Do the read... */		if (jffs2_cleanmarker_oob(c))			ret = c->mtd->read_ecc(c->mtd, start, c->wbuf_ofs - start, &retlen, buf, NULL, c->oobinfo);		else			ret = c->mtd->read(c->mtd, start, c->wbuf_ofs - start, &retlen, buf);				if (ret == -EBADMSG && retlen == c->wbuf_ofs - start) {			/* ECC recovered */			ret = 0;		}		if (ret || retlen != c->wbuf_ofs - start) {			printk(KERN_CRIT "Old data are already lost in wbuf recovery. Data loss ensues.\n");			kfree(buf);			buf = NULL;		read_failed:			first_raw = &(*first_raw)->next_phys;			/* If this was the only node to be recovered, give up */			if (!(*first_raw))				return;			/* It wasn't. Go on and try to recover nodes complete in the wbuf */			start = ref_offset(*first_raw);		} else {			/* Read succeeded. Copy the remaining data from the wbuf */			memcpy(buf + (c->wbuf_ofs - start), c->wbuf, end - c->wbuf_ofs);		}	}	/* OK... we're to rewrite (end-start) bytes of data from first_raw onwards.	   Either 'buf' contains the data, or we find it in the wbuf */	/* ... and get an allocation of space from a shiny new block instead */	ret = jffs2_reserve_space_gc(c, end-start, &ofs, &len);	if (ret) {		printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n");		kfree(buf);		return;	}	if (end-start >= c->wbuf_pagesize) {		/* Need to do another write immediately, but it's possible		   that this is just because the wbuf itself is completely		   full, and there's nothing earlier read back from the 		   flash. Hence 'buf' isn't necessarily what we're writing 		   from. */		unsigned char *rewrite_buf = buf?:c->wbuf;		uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize);		D1(printk(KERN_DEBUG "Write 0x%x bytes at 0x%08x in wbuf recover\n",			  towrite, ofs));	  #ifdef BREAKMEHEADER		static int breakme;		if (breakme++ == 20) {			printk(KERN_NOTICE "Faking write error at 0x%08x\n", ofs);			breakme = 0;			c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen,					  brokenbuf, NULL, c->oobinfo);			ret = -EIO;		} else#endif		if (jffs2_cleanmarker_oob(c))			ret = c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen,						rewrite_buf, NULL, c->oobinfo);		else			ret = c->mtd->write(c->mtd, ofs, towrite, &retlen, rewrite_buf);		if (ret || retlen != towrite) {			/* Argh. We tried. Really we did. */			printk(KERN_CRIT "Recovery of wbuf failed due to a second write error\n");			kfree(buf);			if (retlen) {				struct jffs2_raw_node_ref *raw2;				raw2 = jffs2_alloc_raw_node_ref();				if (!raw2)					return;				raw2->flash_offset = ofs | REF_OBSOLETE;				raw2->__totlen = ref_totlen(c, jeb, *first_raw);				raw2->next_phys = NULL;				raw2->next_in_ino = NULL;				jffs2_add_physical_node_ref(c, raw2);			}			return;		}		printk(KERN_NOTICE "Recovery of wbuf succeeded to %08x\n", ofs);		c->wbuf_len = (end - start) - towrite;		c->wbuf_ofs = ofs + towrite;		memmove(c->wbuf, rewrite_buf + towrite, c->wbuf_len);		/* Don't muck about with c->wbuf_inodes. False positives are harmless. */		if (buf)			kfree(buf);	} else {		/* OK, now we're left with the dregs in whichever buffer we're using */		if (buf) {			memcpy(c->wbuf, buf, end-start);			kfree(buf);		} else {			memmove(c->wbuf, c->wbuf + (start - c->wbuf_ofs), end - start);		}		c->wbuf_ofs = ofs;		c->wbuf_len = end - start;	}	/* Now sort out the jffs2_raw_node_refs, moving them from the old to the next block */	new_jeb = &c->blocks[ofs / c->sector_size];	spin_lock(&c->erase_completion_lock);	if (new_jeb->first_node) {		/* Odd, but possible with ST flash later maybe */		new_jeb->last_node->next_phys = *first_raw;	} else {		new_jeb->first_node = *first_raw;	}	raw = first_raw;	while (*raw) {		uint32_t rawlen = ref_totlen(c, jeb, *raw);		D1(printk(KERN_DEBUG "Refiling block of %08x at %08x(%d) to %08x\n",			  rawlen, ref_offset(*raw), ref_flags(*raw), ofs));		if (ref_obsolete(*raw)) {			/* Shouldn't really happen much */			new_jeb->dirty_size += rawlen;			new_jeb->free_size -= rawlen;			c->dirty_size += rawlen;		} else {			new_jeb->used_size += rawlen;			new_jeb->free_size -= rawlen;			jeb->dirty_size += rawlen;			jeb->used_size  -= rawlen;			c->dirty_size += rawlen;		}		c->free_size -= rawlen;		(*raw)->flash_offset = ofs | ref_flags(*raw);		ofs += rawlen;		new_jeb->last_node = *raw;		raw = &(*raw)->next_phys;	}	/* Fix up the original jeb now it's on the bad_list */	*first_raw = NULL;	if (first_raw == &jeb->first_node) {		jeb->last_node = NULL;		D1(printk(KERN_DEBUG "Failing block at %08x is now empty. Moving to erase_pending_list\n", jeb->offset));		list_del(&jeb->list);		list_add(&jeb->list, &c->erase_pending_list);		c->nr_erasing_blocks++;		jffs2_erase_pending_trigger(c);	}	else		jeb->last_node = container_of(first_raw, struct jffs2_raw_node_ref, next_phys);	ACCT_SANITY_CHECK(c,jeb);        D1(ACCT_PARANOIA_CHECK(jeb));	ACCT_SANITY_CHECK(c,new_jeb);        D1(ACCT_PARANOIA_CHECK(new_jeb));	spin_unlock(&c->erase_completion_lock);	D1(printk(KERN_DEBUG "wbuf recovery completed OK\n"));}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/f99d49adf527fa6f7a9c42257fa76bca6b8df1e3/wbuf.c/clean/fs/jffs2/wbuf.c