Lab FS: Device Files & Symbolic Links

Your task is to extend the xv6 filesystem with support for special device files and for symbolic links. Additionally, there is extra credit available for extending it to support larger files via doubly indirect pointers.

File system in the xv6 book

Before writing code, you should read Chapter 8, File system from the xv6 book and study the corresponding code.

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

$ git fetch origin
$ git checkout -b fs origin/main
$ make clean

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
$ cat /dev/uptime

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.

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. Symbolic links resemble hard links, but hard links are restricted to pointing to file on the same disk, while symbolic links can cross disk devices. Although xv6 doesn’t support multiple devices, implementing this system call is a good exercise to understand how pathname lookup works.

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.

Larger Files (Extra Credit)

The final (and optional) part of this lab is to support larger files for xv6. By default, xv6 only supports files of up to 268 blocks (12 Direct, 256 Indirect). Your task is to increase the size of files xv6 supports by introducing doubly indirect pointers to inodes. This part is worth 15 points.

Without writing any code, if you add largefiletest to your Makefile then you should see the following output:

$ largefiletest
write failed at block number 268 on attempt 0

Expect Long Test Execution Times

After increasing the FSSIZE parameter, usertests will take much longer (e.g., 5+ minutes) to run due to the bigwrite test. Additionally, largefiletest itself takes several minutes to run due to writing a number of blocks and truncating the file repeatedly in a loop. You should only tackle this extra credit portion once you finish the rest of the lab.


You may run python3 to ensure that your code passes all of the tests.

When you are ready to submit your work to Gradescope to be automatically graded, you can run make gradescope which generates a file that can be uploaded to Gradescope. This file should only contain the files that were changed as a result of completing the lab assignment.