| OpSys Spring 2006 - HW5 FAQ |
|   OpSys Home   |   HW5 Assignment |
+ Help!
|
Question: | I have no idea where to start, can give me some suggestions? |
|
Answer: | Start by reading the book. If you don't understand what a file system is, you won't be able to write one... Decide whether you want to build a FAT based filesystem, or an Inode based file system. Some people seem to think using a FAT is easier, others seem to think inodes make more sense... FATIf you are building a FAT based filesystem, you need to decide how
the FAT will be represented in the filesystem. A FAT is really just an
array of integers, the number in slot The next thing you need to decide is who to store the list of files that are in the filesystem (the directory). For each file you need to have the name of the file, the size (in bytes), and the starting block number of the file. If the file takes more than one block to store, the location of the second block is found in the FAT (that's what it's for!). The simplest approach is to simply store the entire directory as a file, so that all you need to know (when starting), is the block number of the first block in the directory. Assuming you use a 4096 byte FAT as described above, you could always use block # 8 as the first block in the directory. The second block of the directory is the value of entry 8 in the FAT (just like for a regular file). To add a file to the file, you need to find enough free blocks to hold the contents of the file, build a linked list by updating the FAT with the appropriate block numbers, add the file name,size and starting block number to the directory, and actually put the contents of the file in the blocks themselves. InodeAn Inode based system doesn't have a FAT, instead information about the blocks in which a file is stored are all place in a special block called an inode. Each file in the filesystem has a inode, which also includes the size of the file. The directory is simpler here, all that the directory needs is a list of file names and inode numbers (for each file name you need to store the inode number - which is the block number that holds the inode for that file). Most of each inode is just a list of block numbers, so you can think of this as an array of shorts (2 byte integers), or you can use ints (4 bytes). 2 bytes is enough since block numbers can only go up to 2047. Assuming your inodes have the file size as a 4 byte integer, followed by 254 2-byte block numbers, you could store all the block numbers needed by a file that fits in 254 blocks, so the maximum file size would be 254*512 = about 128k. You are required to be able to handle files larger than this, so you must be able to support files that require more than one inode to store the list of block numbers. See the text for ideas on how to do this. File I/OIn a real file system, the OS reads a block at a time into memory since it can't hold the entire file system in memory. You can do this, although you can also just read the entire file system into memory, then manipulate parts of this memory and then write the entire thing back into "opsysfs". If you take this approach, you need some code something like this:
/* global variable - this holds the entire file system as a
1Mbyte array.
*/
#define MB 1024*1024
char fs[MB];
void read_fs() {
int fd;
fd = open("opsysfs",O_RDONLY);
if (fs<0)
fatal_error("Error opening opsysfs (for reading)\n");
if (read(fd,fs,MB)!=MB)
fprintf(stderr,"Error reading file system from opsysfs\n");
}
/* write entire buffer to opsysfs */
void write_fs() {
int fd;
fd = open("opsysfs",O_WRONLY|O_CREAT,0755);
if (fs<0)
fatal_error("Error opening opsysfs (for writing)\n");
if (write(fd,fs,MB)!=MB)
fprintf(stderr,"Error writing file system to opsysfs\n");
}
If you do something like the above to read/write the filesystem,
you should realize that fs[0] - fs[511] are the bytes of block 0,
fs[512]-fs[1023] are the byte of block 1, and so on. You can use
/* declaration of the FAT */ short FAT[2048]; ... /* copy the first 4096 bytes from the array fs to the array FAT */ memcpy(FAT,fs,2048*sizeof(short)); |