This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: JFFS2 Garbage Collection Error? (NO! rbtree.c bug)


> 
> That's great!  Are there any other [similar] issues like this in that 
> code?

Actually, there is one other thing that I had to do to get my tests to
run.  Perhaps David can comment...

If on a JFFS2 file you were to:

open();
write( fd, buf, 100 );
close();

an then

open();
read( fd, buf, 50 );
read( fd, buf, 50 );  /* This would fail */
close();

The second read was failing for me.  I had to comment out a check in the
JFFS2 read.c file.  I am not sure what it was doing, but I can't run
with it in.

Take a look at the code below.  Hopefully my mail client will not munge
it too hard.  Look for my "#if 0"

Scott

from: packages/fs/jffs2/current/src/read.c

int jffs2_read_inode_range(struct jffs2_sb_info *c, struct
jffs2_inode_info *f,
			   unsigned char *buf, uint32_t offset, uint32_t len)
{
	uint32_t end = offset + len;
	struct jffs2_node_frag *frag;
	int ret;

	D1(printk(KERN_DEBUG "jffs2_read_inode_range: ino #%u, range 0x%08x-0x%08x\n",
		  f->inocache->ino, offset, offset+len));

	frag = jffs2_lookup_node_frag(&f->fragtree, offset);

	/* XXX FIXME: Where a single physical node actually shows up in two
	   frags, we read it twice. Don't do that. */
	/* Now we're pointing at the first frag which overlaps our page */
	while(offset < end) {
		D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end));
		if (!frag || frag->ofs > offset) {
			uint32_t holesize = end - offset;
			if (frag) {
				D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset));
				holesize = min(holesize, frag->ofs - offset);
				D1(jffs2_print_frag_list(f));
			}
			D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize));
			memset(buf, 0, holesize);
			buf += holesize;
			offset += holesize;
			continue;
#if 0
/* SCOTT - This had to be taken out to get tests to run.
           Seems like it is checking for overlap, but perhaps there
           is a logic problem somewhere because when I print the frag_list
           I don't see any overlap. */
		} else if (frag->ofs < offset && (offset & (PAGE_CACHE_SIZE-1)) != 0) {
			D1(printk(KERN_NOTICE "Eep. Overlap in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n",
				  f->inocache->ino, frag->ofs, offset));
			D1(jffs2_print_frag_list(f));
			memset(buf, 0, end - offset);
			return -EIO;
#endif
		} else if (!frag->node) {
			uint32_t holeend = min(end, frag->ofs + frag->size);
			D1(printk(KERN_DEBUG "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", offset, holeend, frag->ofs, frag->ofs + frag->size));
			memset(buf, 0, holeend - offset);
			buf += holeend - offset;
			offset = holeend;
			frag = frag_next(frag);
			continue;
		} else {
			uint32_t readlen;
			uint32_t fragofs; /* offset within the frag to start reading */
			
			fragofs = offset - frag->ofs;
			readlen = min(frag->size - fragofs, end - offset);
			D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%08x (%d)\n",
				  frag->ofs+fragofs, frag->ofs+fragofs+readlen,
				  ref_offset(frag->node->raw), ref_flags(frag->node->raw)));
			ret = jffs2_read_dnode(c, frag->node, buf, fragofs + frag->ofs - frag->node->ofs, readlen);
			D2(printk(KERN_DEBUG "node read done\n"));
			if (ret) {
				D1(printk(KERN_DEBUG"jffs2_read_inode_range error %d\n",ret));
				memset(buf, 0, readlen);
				return ret;
			}
			buf += readlen;
			offset += readlen;
			frag = frag_next(frag);
			D2(printk(KERN_DEBUG "node read was OK. Looping\n"));
		}
	}
	return 0;
}



-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]