tuesday, 24 april 2007

posted at 14:27

As I've been refactoring fat.handler I've noticed that its gradually change from its original spaghetti into a fairly layered setup - the I/O cache, the FAT, the directory code, the file read/write primitives, then high-level operations code ("create a directory", "delete a file", etc), with the OS interfacing (packet handling, volume management, etc) at the top. This wasn't intentional, but tells me I'm probably thinking about it the right way.

The OS interfacing code should actually be identical for all filesystems, which begs the question - why does every filesystem have to implement it? They shouldn't have to so, just as I intend to seperate out the cache into a library, I also intend to build a library to sit between the OS and filesystem. You could argue that this is redundant, since DOS already provides a filesystem interface. I don't intend to change that though - I'm not going to replace packets, but instead provide some generic handling code that will work for most of what you want to do. If its not suitable, then don't use it - handle the packets yourself.

I think my operations code is the beginning of the model for this. Essentially, the packet handler will accept packets, decode the arguments (ie convert BCPL pointers/strings), ensure that they're sane (eg make sure locks belong to us), then call a function in the filesystem for the requested operation.

I figure the initialisation interface would be something like:

    fs = CreateHandler(FS_Read,      (IPTR) FATOpRead,
                       FS_Write,     (IPTR) FATOpWrite,
                       FS_CreateDir, (IPTR) FATOpCreateDir,

(plus other stuff for setting options or whatever).

Any unspecified operations will result in a "not implemented" error being returned to the caller.

Further, the library would do plenty of checking and munging of arguments so you can always be sure of what you're getting. Locks will always be guaranteed to belong to the filesystem. BCPL strings and pointers would be converted to their C equivalents. Deep subdirectory ops would be fixed up so that every function wouldn't have to know how to parse and munge paths. If I had all this stuff, fat.handler would be vastly simpler than it is now, and when I eventually implement ext2, I wouldn't have to copy/paste anything but just implement the specifics of that filesystem.

Another option for the interface might be to create a "no-op" filesystem base class and have filesystems subclasss it. Its conceptually the same as the above but perhaps the interface is better. I haven't really looked at oop.library so I don't know yet what I'll do with it, but I will experiment further.