You'll start with the code you wrote for Lab 2, and add support for reading and writing file contents. You'll have to choose a representation with which to store file contents in the block server and implement the SETATTR, WRITE, and READ FUSE operations.
% cd ~/yfs % wget -nc http://pdos.csail.mit.edu.ezproxy.canberra.edu.au/6.824/labs/yfs-lab3.tgz % rsync -av l2/* l3 % tar xzvf yfs-lab3.tgz
Note that this will overwrite start.sh and stop.sh with some new, minor bug fixes.
Lab 3 builds upon Lab 2 so make sure you pass the Lab 2 tester before proceeding. When you're done with Lab 3, you should be able to read and write files in your file system. For example, you can use the start.sh script as in Lab 2, and it will start up two separate yfs_servers, mounted at "./yfs1" and "./yfs2", which both use the same extent server for organizing its data:
% cd ~/yfs/l3 % ./start.shThen, you can write files to one directory and read them from the other:
% ls -l yfs1 yfs2 yfs1: total 0 yfs2: total 0 % echo "Hello world" > yfs1/hello.txt % ls -l yfs1 yfs2 yfs1: total 0 -rw-rw-rw- 1 root root 12 Sep 6 20:14 hello.txt yfs2: total 0 -rw-rw-rw- 1 root root 12 Sep 6 20:14 hello.txt % cat yfs2/hello.txt Hello world
Afterwards, be sure to stop your all the processes:
% ./stop.sh
If you try the above commands on your Lab 2 file server, you will get an error.
You are free to store the file contents however you like within the file's extent; however, it should be very straightforward to make a file's extent simply equal to a std::string containing the contents.
If your server passes the tester (see below), then you are done with this part. If you have questions about whether you have to implement specific pieces of FUSE functionality, then you should be guided by the tester: if you can pass the tests without implementing something, then don't bother implementing it.
Please don't modify the test program or the rpc library in any way; we will be using our own versions of these files during testing.
% ./start.sh
Now you can use test-lab-3.pl to test your file system by passing the two directories that were just created:
% ./test-lab-3.pl ./yfs1 ./yfs2 Write and read one file: OK Write and read a second file: OK Overwrite an existing file: OK Append to an existing file: OK Write into the middle of an existing file: OK Check that one cannot open non-existant file: OK Check directory listing: OK Read files via second server: OK Check directory listing on second server: OK Passed all tests % ./stop.sh
If test-lab-3.pl exits without printing "Passed all tests!" or hangs indefinitely, then something is wrong with your file server.
The operating system can tell your file system to set one or more attributes with each SETATTR operation. The to_set argument to your SETATTR handler is a mask that informs the method which attributes should be set. There are really only three attributes you need to worry about (but feel free to implement the others if the mood strikes you), and each has a corresponding bitmask: FUSE_SET_ATTR_SIZE, FUSE_SET_ATTR_ATIME, and FUSE_SET_ATTR_MTIME, corresponding to the file size, last access time, and last modification time of a file. To see if a particular field needs to be set, just AND (i.e., &) the to_set mask with that field's bitmask, and see if the result is non-zero. Then you can find the new value for that attribute in the attr parameter that was passed to your SETATTR handler.
You are free to implement setting these different attributes each in their own RPC, or all together in the same RPC to match the FUSE call. Either way, you'll need to somehow get the new values through the YFS client to the YFS server, and then from the server to the extent server, where it will be visible to other YFS servers using the same extent server.
Note that setting the size attribute of a file can correspond to truncating it completely to zero bytes, truncating it to a subset of its current length, or even padding bytes on to the file to make it bigger. Your system should handle all these cases correctly.
These should be pretty straightforward. A non-obvious situation may arise if the client tries to write at a file offset that's past the current end of the file. Linux expects the file system to return '\0's for any reads of unwritten bytes in these "holes". See the manpage for lseek(2) for details.
% cd ~/yfs/l3 % make clean % cd .. % tar czvf `whoami`-lab3.tgz l3/That should produce a file called [your_user_name]-lab3.tgz in your yfs/ directory. Attach that file to an email and send it to the 6.824 staff address.