Lab: Userspace File System

Assigned
  • February 24, 2026
Due
  • March 24, 2026 11:59pm
Collaboration
    You may work individually or in pairs on this lab. If you choose to work with a partner you may choose your own group. At the end of class on our first day with this lab I will collect a list of groups for this lab.
Submitting
    Submit your completed implementation to Gradescope under the corresponding lab assignment. Make sure your submission includes all of your code and a README that explain how to build and run your userspace filesystem example.

For our third lab, you will implement a filesystem for Linux using the Filesystem in Userspace (FUSE) interface. Normally, the filesystems Linux support rely on code that runs as part of the operating system kernel. With FUSE, we can create new filesystem implementations and attach them to the Linux file tree without touching kernel code.

Most filesystem implementations are meant to manage persistent storage on a disk, but your filesystem will do something different. Instead of directly managing storage, your filesystem will service as an interface to data stored somewhere else. The exact source of data is up to you (with some requirements outlined below) but the example below describes one reasonable choice of data source that you could choose to implement a filesystem for.

Example Filesystem: Zip Archives

For this example, we will consider a FUSE filesystem that provides filesystem level access to the contents of a .zip archive file.

Consider a scenario where you have a .zip file containing some files and directories, and you would like to access those files and directories without having to unzip the entire archive, similar to how Windows allows you to browse the contents of .zip files without extracting them. A userspace filesystem implemented in a program called zip-browser could provide this on Linux via the following command:

$ zip-browser --archive=~/somefile.zip ~/mountpoint

The command above is meant to make the contents of the archive file somefile.zip accessible in the mountpoint directory. The zip-browser program continues running in the background as long as the filesystem is mounted. In UNIX terminology, we “mount” a filesystem by attaching it to the global filesystem tree. All mounted filesystems appear somewhere in the tree rooted at the path /.

Using the terminal to examine the contents of ~/mountpoint after running the zip-browser program should make commands like this possible:

$ ls ~/mountpoint/
a.txt  b.txt  c.txt  somedir

Because the .zip file contents are now visible on the filesystem, you can move into the internal directories and access files within them:

$ cd ~/mountpoint
$ cd somedir
$ ls
d.txt  e.txt
$ cat d.txt
This is a test file.

If zip-browser has support for modifying files, we could even edit the contents of zip files without fully extracting them:

$ echo "Here is a new file" > ~/mountpoint/f.txt
$ ls ~/mountpoint
a.txt  b.txt  c.txt  f.txt  somedir

If file access works in the terminal, it should also work in the Linux file browser, or in most other programs you could use to view or edit files; a few programs may not work well with files stored on a non-standard filesystem, but those should be rare.

When you are finished accessing the userspace filesystem, simply unmount it with the following command:

$ fusermount -u ~/mountpoint

The zip-browser program should exit cleanly at this point. Now that the userspace filesystem is no longer available, the ~/mountpoint directory should be empty.

Requirements

Your task is to implement a userspace filesystem that allows you to access some store of data. This could be .zip files, other archive formats, disk images, or any other data source you choose as long as it can meet the requirements below. Notice that there are two optional elements; you must implement at least one of these, although you can choose to implement both if you like.

FUSE Filesystem
Implement a filesystem using FUSE that can be run on MathLAN. MathLAN currently has version 3.14.1 installed, so make sure you are using this version of the library if you choose to do your development on anything other than a MathLAN computer. As much as possible, please use the tools provided with FUSE that allow you to accept and process command line arguments and run the FUSE application in the background.
Access a Real Data Source
Your FUSE filesystem must provide access to some “real” data source. That means you should not be hard-coding file and directory names in the FUSE application itself; these values must come from somewhere else.
Readable Files
Most or all of the files provided by your FUSE filesystem should be readable, and it should be possible to read these files using standard tools (i.e. a plain text editor, image viewer, etc.). If the data source you are mapping onto a filesystem naturally produces files that require specialized tools to read that is probably okay; just make sure to talk with me first so I know what to expect.
Writable Files Option A
You may choose to add support for writing at least some of the files in your filesystem. Writes should be persistent, meaning the effect of the write should remain visible even after unmounting and re-launching the userspace filesystem. In the .zip file example, that would require modifying the underlying .zip file to reflect the written data. What it means to write to a file will depend on the data source you are presenting as a filesystem, but there should be some reasonable understanding of what writing is if you choose this option. Ideally, writing should allow for modifying existing files and creating new files within the filesystem, but this is not required if it doesn’t make sense for the data source you choose.
Directories Option B
If you prefer, you can add support for directories to your userspace filesystem instead of supporting writing and/or file creation. If you choose this option, there should be some meaningful hierarchical structure within the data source you are presenting that is translated to directories in your filesystem. Talk to me first if you are considering this option so we can talk about whether directories make sense for your data source.
Example
Include an example use of your filesystem in a README file. Make sure to include any necessary data files, and give clear instructions on the commands I will need to run to run through your example. Your example writeup must demonstrate all of the functionality you have implemented to meet the requirements above.

Possible Data Sources

This is an incomplete list of various data sources you could present as a filesystem.

Archive Files
Like the .zip file example above, present the file and directory contents of an archive format.
Disk Images
Implement an actual filesystem (i.e. FAT32) that can interpret the data contained within a disk image file that represents the bytes of data that could be stored on an actual disk.
Websites
Create a filesystem that allows you to navigate across links on a website. You could present basic information about a page (its URL, content, title, etc.) in files with predictable names, and then represents links to other pages as subdirectories.
Game Map
Some games represent game state in a file that you might be able to present as a filesystem. Moving into directories could be analogous to moving through the game map. You could even use command line utilities like the find tool to find paths through the game map.

You are welcome to find and use code from other sources to access the data source you choose, but the filesystem operations themselves must be your own work. If you do use code or libraries from other sources, be sure to include appropriate citations.

Resources

The FUSE library has auto-generated API documentation, but you will likely find the examples more useful for getting started. You can find the example FUSE filesystems for the version installed on MathLAN at https://github.com/libfuse/libfuse/tree/fuse-3.14.0. I recommend that you start by testing the hello.c example to get started.

If you find any other useful references for the libfuse library, please share them with me so I can pass them on to the rest of the class.