eCos gc.c BUG_ON(end > JFFS2_F_I_SIZE(f))
Per Hedblom
per.hedblom at abem.se
Tue Nov 9 15:56:41 EST 2004
Hi,
I have a problem with the eCos version of jffs2 that I posted to the eCos
discuss list.
Ref: http://ecos.sourceware.org/ml/ecos-discuss/2004-10/msg00350.html and
got the recommendation to bring this up here instead.
I have found that jffs2 fails to garbage collect the inode that it currently
adds data to.
The result is that jffs2_garbage_collect_dnode ends with a BUG() call.
I have created a test case that I run on the ecos synt target.
My test stresses the jffs2 with a near to full file system.
I add files until I get ENOSPC and then remove an old file to make space for
a new one.
Here is what happens just before the BUG:
0) The flash is almost full but there should be enough dirty space available
for garbage collect.
1) User level code opens the file /small_files/127 for append (inode #186)
2) Then it request a write of 12000 bytes to file /small_files/127
3) JFFS2 then needs to do some garbage collect to make space for the new
data
jffs2_gc_fetch_inode #169 link=1
jffs2_gc_fetch_inode #167 link=1
jffs2_gc_fetch_inode #166 link=1
jffs2_gc_fetch_inode #172 link=1
jffs2_gc_fetch_inode #172 link=1
jffs2_gc_fetch_inode #178 link=1
jffs2_gc_fetch_inode #173 link=1
4) Then it can write 204 bytes
jffs2_write_inode_range:increasing writtenlen by 204 #186
5) and 84 bytes
jffs2_write_inode_range:increasing writtenlen by 84 #186
6) then it needs to do some more garbage collect and it selects the erase
block containing the #186
jffs2_gc_fetch_inode #186 link=1
7) and the fails in the BUG
BUG() at /home/perhedblom/redhat/ecos/packages/fs/jffs2/current/src/gc.c
1161
----------------------------
The test that fails is BUG_ON(end > JFFS2_F_I_SIZE(f)) in the function
jffs2_garbage_collect_dnode in gc.c.
The problem is that the 288(=204+84) bytes latest written are not added to
the inode->i_size yet but already available in the frag tree.
I can add code to update the inode->i_size in the jffs2_write_inode_range
after each successful write but I don't think this is correct to the jffs2
architecture but it makes the code run.
cvs diff -u -wb -U5 -p write.c (in directory C:\cvs\mtd\fs\jffs2\)
Index: write.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/write.c,v
retrieving revision 1.85
diff -u -w -b -U5 -p -r1.85 write.c
--- write.c 13 Jul 2004 08:58:25 -0000 1.85
+++ write.c 9 Nov 2004 20:28:02 -0000
@@ -436,10 +436,16 @@ int jffs2_write_inode_range(struct jffs2
D1(printk(KERN_DEBUG "increasing writtenlen by %d\n",
datalen));
writtenlen += datalen;
offset += datalen;
writelen -= datalen;
buf += datalen;
+ {
+ struct _inode *inode =OFNI_EDONI_2SFFJ(f);
+ if (offset > inode->i_size)
+ inode->i_size = offset;
+ }
+
}
*retlen = writtenlen;
return ret;
}
I guess that this problem is only related to ecos/jffs2 but I don't know.
Comments?
Per Hedblom
ABEM
More information about the linux-mtd
mailing list