Lab fs: Device files & symbolic links

Your task is to extend the xv6 filesystem with support for special device files and for symbolic links.

To start the lab, update your repository and create a new branch for your solution:

$ git fetch origin
$ git checkout -b fs origin/xv6-19au

Device files

In this part of the lab you will extend xv6 by adding support for four different kinds of device files. These files appear as regular files in the file system hierarchy but are implemented by functions in the kernel instead of being backed by a physical disk.

$ echo hello > /dev/null
$ cat /dev/null
$
$ echo hello > /dev/zero
$ cat /dev/zero
[Never terminates]
$ cat /dev/random
[Infinite stream of random bytes]
$ cat /dev/uptime
19
$ cat /dev/uptime
45
$

When you have implemented these files, you can run the tests in xv6 with specialtest. Your solution must modify init to create the speical files using mknod; the test assumes they already exist. Your solution is complete when the tests produce the following output (and usertests still succeeds):

$ specialtest

START: test /dev/null
reading from /dev/null..
writing to /dev/null..
reading from /dev/null again..
SUCCESS: test /dev/null

START: test /dev/zero
writing to /dev/zero..
reading from /dev/zero..
SUCCESS: test /dev/zero

START: test /dev/uptime
Reading from /dev/uptime..
Reading from /dev/uptime again..
SUCCESS: test /dev/uptime

START: test /dev/random
Opening /dev/random..
reading from /dev/random four times..
SUCCESS: test /dev/random
$

Here’s one reasonable plan of attack.

Challenge: procfs

These device files are limited in that they can only be used to create special files, not directories. Add support for procfs to xv6 to get around this limitation.

The second part of this lab is to add support for symbolic links to xv6. Symbolic links (or soft links) refer to a linked file by pathname; when a symbolic link is opened, the kernel follows the link to the referred file.

For this part of the lab, you will implement a the int symlink(const char *target, const char *linkpath) system call, which creates a new symbolic link at linkpath that refers to file named by target. See the POSIX specification on symlink for further information.

To test, add symlinktest to the Makefile and run it. Your solution is complete when the tests produce the following output (and usertests still succeeds):

$ symlinktest

START: test symlinks
Creating a
Linking b -> a
Writing to a
Reading from b
Removing a
Linking a -> b
Attempting to open b (cycle)
Symlinking c to nonexistent file
Creating symlink chain 1->2->3->4
SUCCESS: test symlinks
$

Here’s one reasonable plan of attack.

Challenge: symbolic links to directories

Add support for symbolic links to directories. This is tricky because the middle components of a path may refer to a symbolic link; you must modify namex to deal with this possibility.

Challenge: rename

Implement the rename system call. Note that it can be tricky to handle all corner cases, for example, when the target already exists or when renaming a directory. Refer to the POSIX specification of rename for details.

This completes the lab. In the lab directory, commit your changes, type make tarball, and submit the tarball through Canvas.