User-Level FUSE Filesystem with Bitmapped Block Allocation and Path Resolution
This project implements a small UNIX-like filesystem in user space using FUSE. It emulates a flat-file “disk” and supports directory and file operations such as mkdir, create, write, read, and readdir.
The system uses:
- A fixed-size disk file (32MB) with 4 regions: superblock, bitmaps, inode region, and data blocks
- A bitmap-based allocation system for inodes and data blocks
- A flat array of inodes and
struct dirent[]-style directory entries - Full path resolution via
get_node_by_path()and directory scanning - A simple write-then-read benchmark that tests small file and directory creation
The goal is to understand low-level filesystem construction—managing blocks, directories, and metadata without kernel support.
-
Disk Emulation via File:
- Simulated disk file (
DISKFILE) of 32MB, created usingftruncate() - Disk access via block-based I/O functions
bio_read()andbio_write()
- Simulated disk file (
-
Superblock and Layout:
- Superblock at block 0 tracks region layout (bitmaps, inodes, data)
MAX_INUM = 1024,MAX_DNUM = 16384- Layout:
- Block 0: Superblock
- Block 1: Inode Bitmap
- Block 2: Data Bitmap
- Blocks 3–66: Inode Region
- Remaining: Data Region
-
Bitmap-based Allocation:
- 1 bitmap for inodes, 1 for data blocks
- Linear scan + first-fit via
get_avail_ino()andget_avail_blkno() - Bit-level manipulation via
set_bitmap(),get_bitmap(), etc.
-
Inode Design:
- Each
inodestores metadata, direct and indirect block pointers - Supports up to 16 direct blocks (max file size = 64KB)
- POSIX-compatible
statstructure embedded forgetattr
- Each
-
Directory Management:
- Directories store fixed-size
struct dirententries - Directory ops:
rufs_mkdir,rufs_opendir,rufs_readdir - Path resolution handled by
get_node_by_path()anddir_find()
- Directories store fixed-size
-
File Operations:
rufs_createallocates and links a new inoderufs_writedynamically allocates blocks as neededrufs_readsupports partial reads, block boundaries, and EOF detection
-
Test & Benchmark Support:
benchmark/test_cases.cruns:- File creation
- Block-aligned writes and reads
- Directory creation
- All tests pass when mounted under
/tmp/mountdir
-
Language:
- C (GCC / Clang compatible)
-
Filesystem Model:
- Block size: 4 KB (
BLOCK_SIZE) - Disk size: 32 MB
- Block device emulation via read/write to flat file
- Block size: 4 KB (
-
Memory Structures:
- Inodes, dirents, and bitmaps laid out contiguously on disk
bio_read()andbio_write()abstract block-level access
-
FUSE integration:
- FUSE 2.6 API (
fuse_main,fuse_operations) - Filesystem operations mapped to user handlers:
rufs_mkdir,rufs_create,rufs_write,rufs_read, etc.- Directory iteration via
fuse_fill_dir_t
- FUSE 2.6 API (
Instructions on how to run this project is in the HowToRun.md file. 🗂️
-
Block Usage:
-
Static Overhead:
- Superblock (1), inode bitmap (1), data bitmap (1), inode region (~64)
-
Dynamic Usage:
- File + directory inodes + data blocks (allocated on-the-fly)
-
-
Test Results:
- All benchmark tests passed:
- File creation and write (16 blocks)
- File read
- Directory creation and listing
- All benchmark tests passed:
-
Limitations:
- Max file size: 64KB (no indirect pointer logic)
- No file unlinking or directory removal (not required for this project)
- No journaling or crash recovery (not expected)
- Kelvin Ihezue, Bryan Shangguan