Hi, (Being I am quite fond of file systems, I had to chime in.)
There is a lot of information about FAT, and if you wish to use USB thumb drives across platforms (one being your own), you will need a FAT driver. The FAT specification can be found
here with some more information found
here.
You might also want to look into the exFAT filesystem. Some USB thumb drives will have this file system on them.
As for hard drive partitions, you may want to look at the LEAN file system, as well as the others mentioned already. Octocontrabass already mentioned the
wiki for file systems.
If you develop on a Windows platform--though since you are asking about FUSE, you may be on a *nix platform--I have a
Windows app that allows me to view and modify image files. You can easily add, delete, or replace a file within an existing partition. Quite a few file systems are supported, but some still need more work.
Now, for how to structure your driver system. The remaining is an example of how you can do it, and is of my own opinion. There may be/are better ways, and there are for sure worst ways.
Create a block of memory holding a number of 4096-byte structures. Each of these structures will represent a device and hold information about this device. The format of the first part of the 4k block is common among all devices. Things like device type, driver entry-point pointer, things like this. The remaining part is unique to the type of device. For example, a hard-drive device will need a place to store the I/O port values, etc. (for IDE type devices), as well as other information the hard-drive driver will need. When the driver is called, via the entry-point pointer, pass a pointer on the stack to this information.
As for file systems, you create another block of memory holding a number of 4096-byte (for example) structures. Again, the format of the first part is common among all file system drivers, while the second part is unique to the file system type. One of the items in the
common area is a pointer to the hard-drive's device structure saved before. You will know which device block this file system will use because you just detected the hard-drive and have the device block ID
on hand. With the pointer to the hard-drive's driver in the file system's common area, the file system driver can call the hard-drive's driver when it needs to read and write sectors/blocks.
With this (simple) type of device/file system structure, you can have an unlimited amount of device and file system types. RAM disk as the device, FAT as the file system. USB thumb drive and the device, LEAN as the file system. etc. The file system is not dependent of the device it resides on as long as all system calls are generic. I.e.: READ_BLOCK always sends the same format of parameters no matter the type of device it is sending to. The device always expects this generic system call format.
A generic device driver system call may expect five parameters:
Code:
bit32s name(struct DEVICE_ENTRY *, bit16u, bit64u, bit64u, void *)
The first is a pointer to the device block (explained earlier), with one 16-bit service number, two 64-bit parameters, and one pointer parameter. If you always make sure the 64-bit parameters are at least the size of a pointer, a specific device may cast one or more of the 64-bit parameters to another pointer.
A generic file system call may expect six parameters:
Code:
bit32s name(bit32u serv, bit64u qword0, bit32u dword1, bit64u qword2, void *ptr0, void *ptr1)
The first is a service number, three parameters (64-bit and 32-bit sizes), and two pointers.
For all generic devices and files systems, this example is quite enough information.
As long as all device drivers expect the same count and size of parameters, any file system can call it. As long as all file system drivers expect a specific count and size of parameters, a user interface app can call it, which in turn will call the underlining device.
It really isn't that complicated, and you can even nest devices deeper than DEVICE <--> FILESYSTEM. For example, you can have a DEVICE <--> CACHE <--> JOURNAL <--> FILESTEM structure, having at least four levels of drivers.
With this type of (simple) system, you can also create a block of memory for partitions. The information in each partition information block has a pointer to the file system driver. A very simple way is to have a partition named "C:\" (the C being the third letter in the English alphabet), using the third entry in the list of partitions. "D:\" would use the fourth, etc. A more relaxed way would to store the name of the partition in the partition structure. For example, name the partition "LEAN001" for the first found LEAN partition. Then when the user interface passes "LEAN001:" to the virtual file system driver, that driver can look through the partition list to find its entry, then know exactly which file system driver to call.
USER_INTERFACE <--> VIRTUAL_FILE_SYSTEM <--> FILE_SYSTEM <--> DEVICE
Hope this helps,
Ben
-
http://www.fysnet.net/osdesign_book_series.htm