[Yaffs] Performance of overwrite vs new file

Charles Manning manningc2 at actrix.gen.nz
Thu Oct 13 02:55:29 BST 2005


> Can YAFFS detect this situation and effectively "unlink" the file first?

There are some subtle issues that make this tricky.

What you're really saying is not so much an "unlink" (even though I know I 
used that term), but a "deletion".

To do this YAFFS would have to detect attempts to resize a file to zero and 
pull some slight of hand to make this happen. I'll explain....

The main issue is really that YAFFS uses object numbers as inode numbers 
(apart from a special case for hard links).  This is nice and simple (apart 
from hard link handling), but has some limitations. 

YAFFS uses obbjectId to identify the chunks (==pages) of data and object 
headers (== file info records) that go with a file.  When we soft delete a 
file all that happens on NAND is that the file is moved into the "unlinked" 
or "deleted" directory and actual deletion is performed by garbage 
collection. The file no longer exists from a Linux perspective so we can do 
whatwever we like with it. Soft deleting essentially says to the garbage 
collector that all chunks related to objectId 123 should be treated as being 
discarded and there is no need to treat them on a one-by-one basis. THis 
blanket treatment saves us a lot of programming time and makes soft delete 
faster.

When we resize a file we cannot treat it this way because the inode still 
exists. Consider the following

 h = open(fname,O_TRUCT | O_RDWR);
write(h,x,500);
close(h);
 // gc happens here

The inode (==objectId), say 123 has been truncated (ie all the data chunks 
discarded), then written to.  Clearly if the gc was told that all data chunks 
for 123 could be deleted, then the gc could delete valid data too.

Thus, at present the way YAFFS does this would be to physically mark the 
truncated chunks. This unfortunately takes time.

OK, so what could could we do about this?

Well one thing to do would be to break the 1:1 relationship between inodes and 
objectIds. This would allow us to delete an object without deleting the 
inode. To explain, I'll run the previous example again.

// Let's say we start with inode 123 = objectId 456

 h = open(fname,O_TRUCT | O_RDWR);
// Opening inode 123 which currently has object id 456.
// Fire sneaky rule:
//   a) Create new objectId 678 scoping the file info out of objectId 456. Fix 
up the mapping so inode 123 <--> 678
//   b) SoftDelete objectId 456.

write(h,x,500);
//  Write to inode 123 == objectId 678.


It would be OK to do this as a "patch table" in yaffs_fs.c. That is, when 
yaffs starts up it starts with the 1:1 mapping numbers and only makes a 
"patch table" for files that have changed.

This would work for resizes to zero, but not resizes to non-zero sizes. That 
probably does not matter since most resizes - probably a good 90% or more - 
are resizes to zero.

I don't know when I would have time to do this, but if someone wants to try 
I'd be interested to see the outcome.

-- CHarles







More information about the yaffs mailing list