[Yaffs] Unexpected erase behavior when rewriting a file on a
nearly empty YAFFS
Charles Manning
manningc2 at actrix.gen.nz
Sat Nov 5 21:26:50 GMT 2005
Peter
Thanx for the feedback. You're essentially describing a proposed change to the
garbage collection policy.
I quite like the idea. It has slight/low impact on NAND, but could be rather
material to NOR folks.
More below:
On Saturday 05 November 2005 06:23, Peter Barada wrote:
> I've got YAFFS working on a NOR-based system, and I'm doing some testing
> on it. If I start with an erased YAFFS, mount it on /mnt/yaffs, and
> then:
>
> # cp /bin/bash /mnt/yaffs
> # cp /bin/bash /mnt/yaffs
>
> I see that calls are made to erase the block(s). I'm wondering why? I
> thought that when chunks are overwritten, that they are marked as
> available for recycling and leave it to the garbage collector to do it.
To recap on how garbage collection works. There are two parts to it:
A) Erasure is kicked off as the result of the last chunk in a full block
becoming unused. We only look at full blocks because we don't want to nuke
the current block being written.
B) The rest of the garbage collection mechanism is there to sweep data so
that space can be reclaimed when the in-use data is sparsely distributed over
the NAND. The way this works is by picking a block with a lot of dirt in it
then copying off the useful stuff and deleting the original. As soon as the
last chunk of useful stuff is copied off, (A) above hapens and the block is
recycled.
To further complicate the story, there's "regular deletion" and "soft
deletion":
Reglar deletion was at one time the only deletion mechanism. When a chunk is
no longer needed, it is marked for deletion and if this caused the pagesinuse
count to get to zero then (A) happens.
When you delete a file, the above would happen a lot, so "soft deletion" was
introduced. This uses a quick marking method to mark all the chunks in the
file without actually programming their deletion markers. The whole file is
marked as deleted and thus this can only be done at a file granularity.
[This is applicable to yaffs1 handling. ie YAFFS1 or YAFFS2 with yaffs1
compatability mode. YAFFS2 never writes deletion markers].
When you do
# cp /bin/bash /mnt/yaffs
# cp /bin/bash /mnt/yaffs
the second cp results in a open with truncation. This does not use soft
deletion, but uses full deletion instead because the whole file is not being
deleted.
If instead you did:
# cp /bin/bash /mnt/yaffs
# rm /mnt/yaffs/bash
# cp /bin/bash /mnt/yaffs
The rm would cause the whole file to be deleted and thus soft delete would be
used instead. That would save the programming of deletion markers and would
spread the erasures through garbage collection cycles.
The above could also be done by the special "resize to zero" handling ideas
that have been semi-proposed and remain on the list of cool things worth
doing.
>
> The callback from yaffs_EraseBlockInNand looks like:
>
> (gdb) where 5
> #0 yaffs_EraseBlockInNAND (dev=0xc06a7000, blockInNAND=13)
> at yaffs_guts.c:352
> #1 0xc010ee16 in yaffs_BlockBecameDirty (dev=0xc06a7000, blockNo=13)
> at yaffs_guts.c:2118
> #2 0xc010fa56 in yaffs_DeleteChunk (dev=0xc06a7000, chunkId=0,
> markNAND=1)
> at yaffs_guts.c:2935
> #3 0xc01103e4 in yaffs_ResizeFile (in=0xc037c132, newSize=0)
> at yaffs_guts.c:3695
> #4 0xc0111374 in yaffs_SetAttributes (obj=0xc037c132, attr=0xc06a7000)
> at yaffs_guts.c:4627
> (More stack frames follow...)
>
> I think the issue is the test:
>
> if(bi->pagesInUse == 0 &&
> bi->blockState == YAFFS_BLOCK_STATE_FULL)
> {
> yaffs_BlockBecameDirty(dev,block);
> }
>
> in yaffs_DeleteChunk. I *think*(but amd not sure) that if this test is
> disabled, the block with all its chunks marked dirty will be left alone
> until *all* the chunks are written and a garbage collection is forced.
Essentially, this (plus probably a few more tweaks) would defer the erasures
until the gc.
There are some interesting issues that would have to be dealt to. For instance
making sure that we never run the free blocks dry.
>
> I also think this will spread out writes even more in the filesystem.
It would spread out erases, I think is what you mean.
>
> Thoughts?
Probably a good idea. Definitely for NOR folks.
Really, the best for NOR is to use asynchronous erasure and erase suspend. ie.
instead of BlockBecameDirty() doing the erase inline, it instead put the block
into a queue for erasure. This would stop th fs stalling on erases as it
currently does.
-- Charles
More information about the yaffs
mailing list