Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
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:
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.
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...
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.
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.
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.
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().
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.
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...
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.)
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.
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?
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.
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?