I'm on my break! Today is just the second day, and still the weekend, so I haven't really done much of anything yet, but it'll happen - all this time is making me giggle :)
I did massive amounts of cleaning on
fat.handler during the week. The cache is being used for all I/O now. It no longer loads the entire FAT into memory which should save quite a bit of memory on large filesystems. That forced me to get into the weirdness of FAT12. As the name suggests, each entry in the FAT is 12-bits wide. So there's no wasted bits, two entries are stored in three bytes. This requires a little bit of math to extract the entry you want, which gets even more complicated if the two bytes needed are split across different disk blocks. The original code never had to deal with this because it had the entire FAT in memory in one long chunk - there was no cache blocks. I'm pretty sure I've got it right - its reading things correctly at least.
So now I've started adding the necessary bits needed for write support. The cache has new functions for marking blocks dirty, though I still have to implement the actual writing stuff. It will have the two standard cache policies available - "write through" where blocks are written immediately when they're marked dirty, and "write back" where some job fires up every now and again and writes out any that have been marked dirty since last time. Writethrough is easier to implement and safer anyway, so I'll just do that for the moment.
I have new (untested) code for writing bytes to a file, which is nearly a straight copy/paste of the read code - I'll have to do something about that. The only major difference is that when it reaches the end of the file, it allocates and links another cluster rather than returning "not found". My algorithm for finding an empty cluster is completely stupid at the moment - it just searches the FAT from the start, every time. Eventually it will start looking around based on where it found a free cluster last time it looked. I'll also be allocating multiple clusters at a time under the assumption that we're no where near writing the end of the file yet. This reduces fragmentation. Obviously if they aren't all used before the file is closed, any left overs get marked as free again. All this is for later though.
Once we're able to write files I'll start looking at formatting fresh FAT filesystems. There's a pile of options that can be provided when creating a filesystem, but the existing
ACTION_FORMAT command is woefully inadequate (being designed for OFS/FFS). I had an idea to allow things to query the handler for information about extended commands and options it supports. The handler could then return a ReadArgs format string to the calling process detailing the arguments it can take for commands (format, check, etc), allowing them to tailor their interface for each filesystem without them having to know the specifics of each themselves. This is something I'll look at in a bit more detail when the time is right.
Time to go put the daughter to bed, then I'll be back into it.