Skip to content

hanna00112/File-System

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Virtual Filesystem (CS355)

Author: Hanna Abrahem

A user-space inode-based virtual filesystem implemented in C/C++. The filesystem is stored in a single binary disk image file and is accessed through a custom shell and a VFS API (libvfs.so).


Architecture Overview

The disk image is divided into fixed regions, each exactly one or more 512-byte blocks:

Block 0        : Superblock
Block 1        : Inode bitmap  (1 bit per inode, 1 = allocated)
Block 2        : Data bitmap   (1 bit per data block, 1 = allocated)
Blocks 3..N-1  : Inode table   (32 inodes max, each with 10 direct + 1 indirect block pointer)
Blocks N..end  : Data region   (file contents + directory entries)

Directory entries on disk use the disk_t struct (24-byte name, inode index, used flag). Each directory inode points to one data block holding an array of disk_t entries (up to 16 entries per 512-byte block).

In memory, the filesystem maintains:

  • superblock* — metadata about block layout
  • inode_table[] — all inode structs loaded into RAM
  • inode_bitmap[] / data_bitmap[] — allocation bitmaps
  • open_file_table[] — runtime open file descriptors (up to 32)
  • fs_root — vnode for the root directory /

Building

make

This builds:

  • libvfs.so — shared library with the VFS API
  • shell — interactive filesystem shell
  • format — disk image formatter
  • print_disk — disk debugging tool
  • All test binaries under test/

Creating a Disk Image

Before running the shell or any tests, a disk image must be formatted:

./format DISK -s 1       # creates a 1 MB disk image named DISK
./format DISK -s 4       # creates a 4 MB disk image

This writes the superblock, bitmaps, inode table, and zeroed data region to the file. Root inode (inode 0) and root data block (block 0) are pre-allocated.


Running the Shell

./shell

The shell loads the DISK image on startup. The following commands are supported:

Command Description
ls List all files and directories in the current directory
mkdir <name> Create a new directory
rmdir <name> Remove an empty directory
touch <name> Create an empty file
write <name> <text> Write text to a file (truncates first)
cat <name> Print the contents of a file
save [name] Save (flush) the filesystem to disk (default: DISK-save)
exit Exit the shell

Any unrecognized command is passed to the OS via fork/execvp.


Working Features

Disk Formatting (format.c)

  • Initializes a fresh disk image of configurable size
  • Writes superblock, inode bitmap, data bitmap, inode table, and zeroed data region
  • Pre-allocates root inode (inode 0) and root data block (block 0)

Filesystem Initialization (init_fs)

  • Loads superblock, bitmaps, and inode table from disk into memory
  • Creates the in-memory fs_root vnode pointing to inode 0
  • Initializes the open-file table

File Creation (f_open with O_CREAT)

  • Scans parent directory's data block for the filename
  • Allocates a free inode from the inode bitmap
  • Writes a new disk_t entry into the parent directory block
  • Flushes updated bitmaps, inode table, and directory block to disk immediately
  • Returns a virtual file descriptor (vfd_t) into open_file_table

File Truncation (f_open with O_TRUNC)

  • Frees all existing data blocks in the inode
  • Resets file size and block count to 0

File Writing (f_write)

  • Writes bytes at current file offset (tracked per open descriptor)
  • Allocates new 512-byte data blocks on demand as content grows
  • Supports files up to 10 blocks (5120 bytes) via direct block pointers
  • Updates file size in inode if write extends end of file
  • Flushes data bitmap and inode table to disk after every write

File Reading (f_read)

  • Reads from current file offset, block by block
  • Clamps read to actual file size (no reading past EOF)
  • Advances file offset after each read

Close (f_close)

  • Frees the in-memory vnode and open-file table slot
  • Flushes disk buffers

Directory Listing (f_opendir / f_readdir / f_closedir)

  • Opens a directory as a descriptor in open_file_table
  • f_readdir steps through disk_t entries in the directory's data block, skipping unused slots
  • Returns name, inode number, type, and size for each entry

Directory Creation (f_mkdir)

  • Allocates a new inode and a new data block for the directory
  • Zeroes the directory's data block on disk
  • Adds an entry to the parent directory
  • Flushes all metadata to disk

Directory Removal (f_rmdir)

  • Verifies directory exists and is empty
  • Frees inode and data block bits
  • Removes entry from parent directory
  • Flushes all metadata to disk

File Lookup (find)

  • Scans all direct block directory entries of a given directory vnode
  • Returns a freshly allocated vnode if found, NULL with ENOENT otherwise

Save (save_fs)

  • Flushes in-memory superblock, bitmaps, and inode table to the current disk image
  • Optionally copies the entire disk image to a new file if a different name is provided

Cleanup (cleanup_fs)

  • Closes disk file handle
  • Frees all heap-allocated filesystem state (superblock, bitmaps, inode table, fs_root)

Disk Inspector (print_disk)

  • Standalone tool to dump the disk image without mounting it
  • Prints superblock fields, allocated inode/data bitmaps, and inode table metadata

File Structure

.
├── format.c        # Disk formatter
├── vfs.c           # Core VFS implementation
├── vfs.h           # VFS API and struct definitions
├── inode.h         # Superblock and inode struct definitions
├── shell.c         # Interactive shell
├── libparser.c/h   # Command-line parser
├── print_disk.c    # Disk image debugging tool
├── Makefile
└── test/
    ├── test_open.c
    ├── test_write.c
    ├── test_read.c
    ├── test_save.c
    ├── test_find.c
    ├── test_fileexist.c
    ├── create.c
    └── create-eexist.c

Running Tests

Each test binary operates on the DISK image. Make sure a freshly formatted disk exists before running:

./format DISK
./test/test_open
./test/test_write
./test/test_read
./test/test_save
./test/test_find
./test/create-eexist

About

A user-space inode-based virtual filesystem implemented in C

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages