Problem deleting files with NAND/JFFS2 and a possible solution

Howard Gray rhea at matrix-vision.de
Tue Jan 27 06:47:41 EST 2004


Hi,

I am using kernel 2.4.20 with the latest cvs MTD version. The system is a  
PowerPC-based embedded device with both NOR and NAND flash. I have a 
partition in NAND flash using JFFS2 as the file system. 

If I mount a JFFS2 partition, delete a single file and unmount again, 
everthing is o.k. 

But if I mount the JFFS2 partition, delete a file and then (after a long pause 
to ensure the garbage collector has finished) turn off the device without 
unmounting, the file reappears after the reboot and new mount command. There 
are various variations on this like mounting read-only before unmounting etc. 
(with this device, I cannot assume that a user turns off this device in a 
controlled way....)

It appears as if just deleting a file is not enough to mark any inodes as 
dirty so that kupdated ignores them. It doesn't matter how long you wait for 
the GC to be started because it won't be unless you do something else to the 
file system too, like creating a new file or sending a SIGHUP to the GC. For 
the same reason a "sync" doesn't help either.

After some time I came to the conclusion that there is a problem in the 
function "jffs2_full_dirent" in the file "fs/jffs2/write.c". A call is made 
to "jffs2_flash_writev" which has as its final parameter an inode number 
(assuming alloc_mode is not ALLOC_GC). It looks like this:

write.c: approx. line 282.....

    ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen,
                 (alloc_mode==ALLOC_GC)?0:fd->ino);

"fd->ino" would appear always to be "0" in the case where a file is just being 
deleted which, in turn,  at the end of "jffs2_flash_writev" stops the inode 
being dirtied (i.e. the superblock's "s_dirt" flag is not set to "1"): Here's 
the call at the wnd of "jffs2_flash_writev":

wbuf.c: approx. line 752.....

    if (c->wbuf_len && ino)
        jffs2_wbuf_dirties_inode(c, ino);


I'm not sufficiently knowledgeable about the internals of JFFS2 to supply a 
proper patch, but it would seem to me that the call to "jffs2_flash_writev" 
in write.c at line 282 should be like this:

Suggestion....
write.c: approx. line 282.....

    ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen,
                 (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino));

This would appear to be the inode of the directory entry and this is really 
what we are changing when we delete a file, or am I missing something here ? 
In any case, this change seems to have the desired effect and the problem is 
cured.

Any comments would be appreciated. Thanks.

--
Howard









More information about the linux-mtd mailing list