Page 1 of 2
handling filesystems
Posted: Wed May 23, 2007 8:01 am
by AndrewAPrice
I completely deleted my old hard coded (FAT12 on a floppy) file functions and started writing a more universal extend-able system. I've finished implementing my read-only storage device manager (write support should be easy to add), and any device is now accessable through this function:
Code: Select all
extern int storage_readdevice(int number, int offset, int length, char *buffer);
Number represents the device number (assigned in the order they're detected; 0 - null device, 1/2 - floppy drives, etc).
Anyway, my problem now is; how do I set up and organise a unified file-system model (such as setting up a VFS to mount devices under)?
Posted: Wed May 23, 2007 9:59 am
by mathematician
I can only speak about my own intentions. Personally I would associate a file system driver with each partition, based upon the partition type flag, and then call the appropriate driver whenever a partition was accessed. Each driver would be expected to support a standard set of functions, such as open/close file read from a file, write to a file, etc, as well as some optional ones which it might support (such as hide a file or create a hard link). The drivers would be asked to indicate whether they support each optional feature or not. If a user, or application, tried (for example) to hide a file on a system which didn't support hiding he would get an error message.
That is all theory at the moment, and I haven't even begun the process of trying to implement it.
Posted: Wed May 23, 2007 10:47 am
by urxae
mathematician wrote:Each driver would be expected to support a standard set of functions, such as open/close file read from a file, write to a file, etc, ...
You probably don't want writing to be mandatory functionality. Otherwise you can't write a driver for a normal cd/dvd-rom drive...
Posted: Wed May 23, 2007 7:29 pm
by AndrewAPrice
I'm thinking about giving each partition a string identifier, which is part of a struct that also contains the device number, the file system to use, and the offset/size of the fs.
Should I keep a cache of known files in the VFS? Or, when I call vfs_getdirentries (e.g. with "\floppy\system\") should it call the FS driver (find the fs associated with the "floppy" entry, and then call the fs's getdirentries with "\system\"). This seems the most dynamic way, but it seems slow if a program keeps requesting the contents of a directory.
Posted: Thu May 24, 2007 2:10 am
by AndrewAPrice
One more thing; would writing an ext2 driver be easier than re-writing a FAT12 one? I'm asking this because my old FAT12 driver was a helluva headache to work out! And it's still doesn't work properly.
Posted: Thu May 24, 2007 2:23 am
by pcmattman
Why FAT12? FAT12 is the hardest FAT to write a driver for. FAT16 and FAT32 aren't as hard.
FAT isn't hard though, you just need good disk i/o functions for it to work.
Posted: Thu May 24, 2007 2:43 am
by AJ
urxae wrote:You probably don't want writing to be mandatory functionality. Otherwise you can't write a driver for a normal cd/dvd-rom drive...
I was just thinking about this - I suppose one way of doing it would be to have mandatory read/write functions, but have a way of querying whether the write functionality is supported - if not, EOF would just be returned on every attempted read.
Posted: Thu May 24, 2007 2:57 am
by jnc100
urxae wrote:You probably don't want writing to be mandatory functionality. Otherwise you can't write a driver for a normal cd/dvd-rom drive...
Read-only is a property of the media within the device, not of the filesystem.
Each filesystem should be able to implement (accoding to Redhat's newlib):
close, link, open, read, unlink and write
Consider, for example, a FAT file system on a write-protect floppy disk. You wouldn't make a special read-only FAT for this filesystem, but rather report errors on any attempt to write to it. I suppose the only exception is iso9660 where you probably wouldn't bother to write more than a stub for write().
Regards,
John.
Posted: Thu May 24, 2007 3:32 am
by mathematician
MessiahAndrw wrote:One more thing; would writing an ext2 driver be easier than re-writing a FAT12 one? I'm asking this because my old FAT12 driver was a helluva headache to work out! And it's still doesn't work properly.
If you are going to support floppy disks I think FAT12 is the only real option. Back in the days of yore Microsoft didn't go for a 12 bit FAT because they wanted to make life difficult for their own programmers, but because of the severe space limitations on a 360kb floppy. Things are obviously a bit better on a 1.44mb floppy, but not much. A boot sector, two 12 bit FATs and a root directory will occupy all but three sectors of track 0. In fact I'm not sure FAT16 would fit on without a smaller root directory.
I would say that anything more sophisticated than a FAT system is definitely not a luxury you can afford on a floppy.
Posted: Thu May 24, 2007 3:45 am
by AJ
mathematician wrote:
I would say that anything more sophisticated than a FAT system is definitely not a luxury you can afford on a floppy.
I would add to that that AFAIK most OS's support FAT12 floppy's and FAT16/32 HD partitions in some form or another.
If you intend to install your OS on a computer alongside another OS, being able to write to your OS partition or your boot floppy from Windows/Linux should be a real advantage for doing updates etc...
Cheers,
Adam
Posted: Thu May 24, 2007 3:46 am
by mathematician
MessiahAndrw wrote:I'm thinking about giving each partition a string identifier, which is part of a struct that also contains the device number, the file system to use, and the offset/size of the fs.
Should I keep a cache of known files in the VFS? Or, when I call vfs_getdirentries (e.g. with "\floppy\system") should it call the FS driver (find the fs associated with the "floppy" entry, and then call the fs's getdirentries with "\system"). This seems the most dynamic way, but it seems slow if a program keeps requesting the contents of a directory.
Myself, I would keep a copy of the current directory, inodes for any open files, and a cache of recently read/written data in memory. nothing else - at least without thinking about it more deeply. (Once you have got the basic design, for something there is nothing like coding the thing to make you think deeply about it.)
Posted: Thu May 24, 2007 4:07 am
by AndrewAPrice
pcmattman wrote:Why FAT12? FAT12 is the hardest FAT to write a driver for. FAT16 and FAT32 aren't as hard.
FAT isn't hard though, you just need good disk i/o functions for it to work.
Do I need anything more than
Code: Select all
extern int storage_readdevice(int number, int offset, int length, char *buffer);
in my storage drivers? (I'm concentrating on read only file systems right now, but I also have a storage_writedevice(int number, int offset, int length, char *buffer))
I read entire blocks at a time using 512 as the length.
Posted: Thu May 24, 2007 4:18 am
by AndrewAPrice
Also, what do I need in my FILE struct? I'd use it for identifying files, such as:
Code: Select all
FILE myFile = fopen("\floppy\hello.txt");
int i;
char c;
for (i = 0; i < flength(myFile); i++)
{
fread(myFile, i, 1, c);
/* FILE, offset, length, buffer */
screen_putch(c);
/* put character */
}
fclose(myFile);
I was thinking of myFile containing the name of the file ("\hello.txt"), the mount point ("floppy"), and a pointer to the FAT directory entry - but I can't include this, it's FS specific!
What do people have in their FILE struct? What could I use that's FS-independent, and could be passed to any file system driver to perform file operations?
Posted: Thu May 24, 2007 4:42 am
by AJ
Hi,
This confused me initially - have a look at solar's PDCLib on sourceforge. Note that FILE in C does not necessarily even refer to an on-disk file. When an app uses a FILE ptr, it is up to your OS (not the libc) to decide which device needs to handle the reads and writes.
Cheers,
Adam
Posted: Thu May 24, 2007 5:01 am
by AndrewAPrice
Thanks, but errrr... I followed stdio.h all the way back to /trunk/platform/example/internals/_PDCLIB_config.h and I couldn't find the FILE struct.
Instead of telling me to look at code, can someone give some practical theory behind what they use in their OS?
How do your file systems, mountpoints/VFS, and file operations interact? What exact information do you pass between them? How does a user program request a file? What exactly is communicated between the fopen<->SomeFS_open (or equivalent functions)? What steps do you take internally?
Thanks for all your help so far.
![Smile :)](./images/smilies/icon_smile.gif)