Common to the 'native' disk filesystem, FAT filesystem and ISO9660 filesystem drivers is the virtual disk filesystem driver, oz_dev_vdfs.c. It was created as there would otherwise be much common code between various disk-like filesystem drivers. It is more a subroutine library than a real device driver (as there is no device table entry for it).
The 'native' disk file system driver is in oz_dev_dfs.c. There is nothing super-special about it, except it has one of my favoUrite VMS things, version numbers.
Now I have had days where I work on something and make a complete mess of it (ENbugging session). So, with version numbers, I can tell it to d'l33t everything I did today, or since 12:34pm or whatever. Because when I exit the editor, it makes a new version of the file, leaving the old one intact!!
For example, I have a source file oz_kernel_486.s. Well, it's real name (as of today) is oz_kernel_486.s;878. This means I have edited that thing 878 times (it seems like it has been 8878 times ;). Now I don't have all the old versions as I have occasionally purged some of them. But I looked and I do have version ;5 (dated 2-OCT-1998). Jeez, how could I have possibly thought that the stuff in that file would stand a chance of working, anyway?
Now to access the file, I can just specify the simple name oz_kernel_486.s. The filesystem knows that if there is no version number specified, that I want the highest numbered (latest) version of the file. Or I can tell it exactly which version I want by putting the ;5 or whatever on the end. Also, I can say, give me the next to latest file by specifying ;-1, or go back two versions with ;-2, etc.
When I create a file without specifying a version number, it creates a version number one greater than the highest version that currently exists. Negative version numbers don't make any sense when creating files, so they are illegal.
Well, neither Unix nor NTwit have that. PDP's had it in RSX. So now at last I have a PC-based OS with the dam things.
I have recently (Dec 16, 2001) made a binary search for filenames and moved the wildcard scanning out of the kernel thread so it can run independently. I tested it by creating 200,000 files in a directory (on an ultra-wide scsi drive!), in such a way as to cause maximal fragmentation for the directory and for the index header file (inode table).
My layout is fairly basic.
This directory is formatted the same as any other directory on the disk
It is an array of 512-byte blocks, indexed by the file number. Each block contains this basic info about the file:
It is just a simple array of bits, one bit per index file header. One indicates the header belongs to an active file. Zero indicates the file that header was for is deleted and can be re-used.
It is a simple array of bits, one bit per cluster. One indicates the cluster is occupied. Zero indicates the cluster is available.
The placement of the boot block is hardware dependent, therefore this file's placement is hardware dependent. Anyway, the first block(s) contain the bootblock(s), and the last block contains the volume homeblock.Contents of volume homeblock:
Directories are made up of buckets (pronounced 'boo-kays') that are one cluster in size. Each bookay contains records with the following layout:
I also implemented the FAT filesystem (oz_dev_fat.c). It handles FAT-12, -16 and -32, as well as long filenames.
The ISO9660 CDROM file system driver is in oz_dev_cdfs.c. It is able to handle Rockridge* filename extensions. It behaves as a normal filesystem driver except it cannot handle any write-type calls (duh). It uses the oz_dev_vdfs.c virtual disk driver library.
*Hep me! Hep me! Do what he say! Do what he say!
There is also another filesystem driver called oz_dev_ip_fs.c. It is used as an nfs-like client for downloading files over the internet. The server runs on the linux computer and is in ip_fs_server_linux.c. It does not use the vdfs driver at all as it is more network-based than disk-based.
These routines are fairly crude and should just be used for downloading the OS files. So I generally just include the driver in the loader. There is no protection checking and the server can only handle one mount point and processes all requests one at a time. It also uses UDP and a very simple retry mechanism.
But it serves its function. My boot block on my hard drive loads my loader from the hard drive into memory. Then the loader fires up this driver to download my latest-and-greatest kernel and any other stuff the loader script says from my linux box onto the OZONE hard drive. Then it boots the kernel from the hard drive that it just downloaded.
It is possible (and I have done it before) to directly boot from this driver, ala diskless workstation. But this driver's performance isn't all that great, so it is of limited usefulness. The transfer rates I get are around 200-300 KB/sec on a 10Mbit ethernet. But it works.
I didn't use nfs because it probably was overkill for what I wanted and I didn't want to make a career out of getting this to work. I wanted something more along the lines of tftp, but tftp didn't support positioning of the file and listing directories, so I couldn't use it for a general filesystem driver.
Another limitation of this driver is that it is read-only. It has no functions to write files back to the linux box. You have to fire up a full OZONE system and run the ftp daemon oz_util_ftpd.c to transfer files back to linux or VMS (or whatever).