Systems Programming Project

Virtual File System

Overview

I built a virtual file system in C that operates on top of a virtual disk, implementing core file system concepts such as mounting, unmounting, file creation, file deletion, open file tracking, and persistent block-based storage.

The system uses a superblock, a FAT-style allocation structure, and a root directory to organize files and manage data blocks. It supports common file operations such as read, write, seek, and stat while maintaining file offsets for open descriptors.

Core Capabilities

  • Mount and unmount a virtual file system
  • Create, delete, open, and close files
  • Track open file descriptors and offsets
  • Read and write file contents across disk blocks
  • Seek within files and query file size
  • Persist metadata and data to a virtual disk

What I Learned

This project gave me hands-on experience with how file systems organize persistent data on disk, including allocation, metadata layout, and open-file state management. It also reinforced how small implementation details such as offsets, boundary conditions, and FAT updates can affect correctness across the entire system.

On-Disk Layout

The file system is organized around a superblock describing the disk layout, a FAT structure for block allocation, a fixed-size root directory, and data blocks used to store file contents. This structure provides a compact but realistic model of how a disk-backed file system works.

File Management

Files are stored in the root directory with metadata such as file name, size, and starting block. Open files are tracked through a separate table that stores file descriptor state and current offsets for reads and writes.

Block Allocation

File contents are stored across data blocks and linked through a FAT-style allocation table. This allows the file system to handle files spanning multiple blocks while supporting append, overwrite, and partial reads or writes.

Persistence

Metadata structures and file contents are written back to the virtual disk so that files persist across mount and unmount cycles. This makes the project a true disk-backed system rather than an in-memory simulation.

Interface Surface

The implementation supports the key file system operations expected from the provided interface, including mounting, directory management, and random-access file operations through file descriptors.


        Supported operations:
        - fs_mount(...)
        - fs_umount()
        - fs_info()
        - fs_create(filename)
        - fs_delete(filename)
        - fs_ls()
        - fs_open(filename)
        - fs_close(fd)
        - fs_stat(fd)
        - fs_lseek(fd, offset)
        - fs_read(fd, buffer, count)
        - fs_write(fd, buffer, count)
        

Validation & Testing

Since this project is a backend systems implementation, correctness was demonstrated through scripted and programmatic tests rather than a GUI. The provided test harness covered behaviors such as small reads/writes, multi-block writes, overwrite cases, overread handling, offset-based reads, and other boundary conditions that are critical in file system logic.


        Example testing scenarios:
        - create → open → write → seek → read
        - write data across multiple blocks
        - overwrite existing file regions
        - read past current offset / file boundaries
        - mount → persist → unmount → remount → verify contents
        

Challenges

One of the main challenges was correctly handling block-oriented storage while still exposing a byte-oriented file interface. Reads and writes had to work correctly both within a single block and across block boundaries, while keeping metadata, FAT entries, and file size consistent.

Managing file offsets and ensuring that data remained correct after seeking, remounting, and partial overwrites required careful debugging and strong attention to edge cases.

Why It Matters

This project helped me understand how higher-level file operations map onto low-level disk structures. It strengthened my systems programming skills and gave me experience implementing persistent storage, metadata management, and file access semantics from the ground up.

Notes

Source code is available upon request due to academic collaboration constraints. The project was validated using the provided testing framework and custom created scripts designed to stress file system behavior across realistic edge cases.