Assignment/S5FS (167)
From WoxWiki
| Assignment Out: | Nov. 11 (Wednesday) |
| Assignment Due: | Dec. 10 (Thursday 11:59PM) |
This is the third and final CS167-only project. Once you finish this you are done! CS169 students have their own version of the same project here.
Please remember to read the course Programming Guide for good style guidelines.
Contents |
Introduction
In this assignment you will be working in the s5fs/ directory of your source tree to implement the Weenix version of the s5fs file system. Your disks will be stored in files on the host operating system (the deploy/disk-* files). You can create new disks using the fsmaker utility in the course bin directory. It should be in your path.
You will need to change the line:
S5FS = 0
in your Makefile.defines to:
S5FS = 1
Also, in order to use your s5fs file system instead of testfs you will need to change the lines:
ROOTFS = testfs # ROOTFS = s5fs
to read:
# ROOTFS = testfs ROOTFS = s5fs
Remember to run make clean once these changes are finished.
You will be implementing both the s5fs interface to the vfs as well as the s5fs specific routines that interact with the disk access functions. Make sure to check the Hackers Guide section on the S5FS file system.
VM Pages
While working on this part of Weenix you will not need to directly read and write from the disk. Instead you will use the VM page functionality of Weenix to read blocks of data from disk and the pageout daemon will take care of writing your dirtied pages back to disk. This also means that only pages you mark as dirty will be written back to disk, so any time you change a page, don't forget to dirty it (remember the indirect block as well).
You should make sure to read about VM pages in the Hackers Guide. The functions you will want to look out for are:
int vm_page_get (struct vm_object*, unsigned, vm_page_t **); void vm_page_pin (vm_page_t *); void vm_page_unpin (vm_page_t *); void vm_page_dirty (vm_page_t *);
You should also read the comments for these functions in the source code for more detailed information about them.
General Coding Notes
Error Checking
You should always check for things that can go wrong. When you detect an error you should usually return -errno where "errno" is the error number that indicates the type of error that occurred. For example, if the vnode_t* passed to s5fs_readdir() does not represent a directory, you should return -ENOTDIR (not panic). You should always check the return value from functions which can fail, and if the returned value is negative you should usually return it as well. Returning -1, is not a good idea here at all. We have tried to indicate some errors that you should check for in the comments, but we have not mentioned all of them, so you should go over your code thoroughly to make sure that you handle all possible errors.
Inode Reference Counts
s5_inode_ts have a s5_linkcount field which is a reference counter. To get inodes you need to use the vm_page_get() function (the S5_INODE_BLOCK could be useful here) then use the VM page's vp_paddr field together with the S5_INODE_OFFSET macro to get the inode. Since you are working in the S5FS system you are allowed to use ++ and -- to directly modify the link count. Do not forget to pin pages you are working with so that they are not uncached prematurely.
Assignment
The code for this assignment is primarily contained in two files: s5fs/s5fs.c and s5fs/s5fs_subr.c. The functions in s5fs/s5fs.c act as the implementation of the VFS interface for file systems. Thus when the VFS needs something from an S5FS filesystem it will make calls to these functions. The functions in s5fs/s5fs.c then use the functions in s5fs/s5fs_subr.c. To actually interact with the disk.
As usual the manpages are a great resource when coding the functions in s5fs/s5fs.c. You will probably also want to have information about the VFS assignment hand, as the expected semantics of many of the functions in s5fs/s5fs.c are defined there.
You should read all of the functions in these two files even if you do not need to write them.
Functions you will need to write in s5fs/s5fs.c:
int s5fs_read_vnode (vnode_t *vn); void s5fs_delete_vnode (vnode_t *vn); int s5fs_read (vnode_t *vn, int offset, void *buf, int len); int s5fs_write (vnode_t *vn, int offset, const void *buf, int len); int s5fs_create (vnode_t *vn, const char *name, int namelen, vnode_t **result); int s5fs_mknod (vnode_t *vn, const char *name, int name_len, int mode, devid_t devid); int s5fs_lookup (vnode_t *base, const char *name, int namelen, vnode_t **result); int s5fs_link (vnode_t *src, vnode_t *dir, const char *name, int name_len); int s5fs_unlink (vnode_t *vdir, const char *name, int namelen); int s5fs_mkdir (vnode_t *vdir, const char *name, int name_len); int s5fs_rmdir (vnode_t *parent, const char *name, int name_len); int s5fs_readdir (vnode_t *vn, int offset, struct dirent *d); int s5fs_stat (vnode_t *vn, struct stat *ss); int s5fs_readpage (vnode_t *vnode, int offset, void *pagebuf); int s5fs_dirtypage (vnode_t *vnode, int offset); int s5fs_writepage (vnode_t *vnode, int offset, void *pagebuf);
Files you will need to write in s5fs/s5fs_subr.c:
int s5_seek_to_block (vnode_t *vnode, int seekptr, int alloc); void lock_s5 (s5fs_t *fs); void unlock_s5 (s5fs_t *fs); int s5_write_file (vnode_t *vnode, int seek, const char *bytes, int len); int s5_read_file (vnode_t *vnode, int seek, char *dest, int len); int s5_alloc_block (s5fs_t *fs); int s5_find_dirent (vnode_t *vnode, const char *name, int namelen); int s5_remove_dirent (vnode_t *vnode, const char *name, int namelen); int s5_link (vnode_t *vnode, s5_inode_t *child, const char *name, int namelen); int s5_inode_blocks (vnode_t *vnode);
Helpful Tools
There are several tools lying around on the system which may or may not be useful when writing your file system.
Hex Dumps
There are three utilities you might want to use to inspect your disk files (remember to fetch your disk before inspecting it).
-
odcan create hex and octal dumps of your disk files. Check out its manpage. -
xxdis a stand alone tool distributed with vim. It is similar toodbut has a few extra fancy features. -
emacshas a binary editing mode.
Lets do an example. Say I want to print out the superblock of my simdisk. If the superblock contains 6 words at 4 bytes each. To print out the 1st 24 bytes and group the bytes into words I could do this:
$ xxd -g 4 -l 24 simdisk 00000000: 0000727f 0000001c 00000072 00000000 ..r........r.... 00000010: 00000280 00000002 ........
fsmaker
In the course bin directory there is a fsmaker binary which can create simdisks, get refcounts, give you a hexdump of a certain block.
Test Code
We give you some test code including the s5fs_privtest.c file which will call a bunch of do_xxxx() functions to give your file system a workout. To start the s5fs_privtest.c tests call s5fs_start(). If you pass NULL as the path it will use / as the root of the test directory. If you are running multiple of these tests at the same time it would be a good idea to pass a different test root to each of them so that they do not interfere with each other.
Also it would be a good idea to try all of your test cases for VFS again. This will further test both your S5FS and VFS implementations.
Handing In
As usual, run the handin script:
$ /course/cs167/bin/cs167_handin s5fs
