๐ Overview
A FUSE-based overlay filesystem written in Rust that stacks a read-only lower layer under a read-write upper layer, exposing a unified mount point with full Copy-on-Write (CoW) semantics, whiteout-based deletion, and flexible commit strategies.
OverlayFS-Fuse provides a simple and robust way to create ephemeral writable environments over immutable directories.
It is designed for scenarios such as:
-
๐ฆ Portable Linux application packaging;
-
๐ ๏ธ Temporary build environments;
-
๐งฉ AppImage-style runtime overlays;
-
๐งฑ Container-like rootfs sessions without full container runtimes;
-
๐ Safe modification layers over read-only systems;
Unlike kernel OverlayFS, this implementation runs entirely in userspace via FUSE, making it usable without special kernel privileges in many environments.
The system works by combining three layers:
| Layer | Role |
|---|---|
| Lower | Original read-only filesystem |
| Upper | Writable layer containing modifications |
| Mountpoint | Unified view exposed to applications |
All writes occur in the upper layer, preserving the original filesystem intact until an explicit commit is requested.
โจ Features
-
๐ Copy-on-Write
Writes are promoted to the upper layer; the lower layer is never modified. -
๐๏ธ Whiteout support
Deletions and renames create.wh.<name>markers to hide lower-layer entries. -
๐ Four finalization strategies
Preserve,Discard,Commit, andCommitAtomic(crash-safe backup/swap merge). -
๐ Symlink-aware
Dangling symlinks in the lower layer are tolerated; CoW never follows symlinks when copying. -
๐งฌ Extended attribute preservation
xattrs, permissions, ownership, and timestamps are carried through CoW and commits. -
๐งฎ Dual inode modes
Virtual(sequential, ephemeral) orPersistent(FNV-1a hash, stable across remounts). -
๐ Thread-safe inode store
Single-Mutexdesign eliminates TOCTOU races in concurrent lookup/allocation. -
๐งพ Content-based deduplication on commit
Files are compared by size, mtime, and BLAKE3 hash before overwriting.
๐ Full Lifecycle Example
This example demonstrates the complete flow: configuring, mounting, interacting with the filesystem, and finally committing the changes back to the base directory.
use ;
use PathBuf;
// 1. Create an overlay over an existing directory.
let mut overlay = new.mountpoint_as_home;
// 2. Mount โ changes go to <lower>.upper, visible at <lower>.mountpoint
overlay.mount.expect;
// 3. Use the mount point like any normal directory.
let mp = overlay.handle.mount_point.to_path_buf;
write.unwrap;
// 4. Unmount and decide what to do with the changes.
overlay.umount;
overlay.overlay_action; // merges upper โ lower
๐ Custom upper path
You can override the default storage for modifications. This is useful for redirecting writes to a specific persistent disk or a custom session folder.
let mut overlay = new;
overlay.set_upper;
overlay.mount.unwrap;
๐งฑ Persistent inodes
By default, inodes are virtual and ephemeral. Use Persistent mode if your application relies on stable inode numbers across different sessions (e.g., for some database engines or backup tools).
use InodeMode;
let mut overlay = new;
overlay.set_inode_mode;
overlay.mount.unwrap;
๐ ๏ธ State Safety & Prevention
OverlayFS prevents configuration changes after the filesystem is already live. This safeguard ensures that your mount point and inode logic remain consistent.
let mut overlay = new;
overlay.mount.expect;
// The following will PANIC at runtime to prevent configuration drift:
// overlay.set_upper(PathBuf::from("/new/path"));
// overlay.mountpoint_as_home();
๐ Environment-Aware Mounting (Fluent API)
Use mountpoint_as_home() to automatically redirect the mount point to the user's local cache. This is ideal for environments where writing to /tmp is restricted or where you want to keep the host system clean.
use InodeMode;
let mut overlay = new
.mountpoint_as_home // Relocates to ~/.cache/mount_...
.set_inode_mode
.set_upper;
overlay.mount.expect;
๐งช Parallel Testing Support
The new naming convention uses session IDs and timestamps, allowing multiple instances of the same application or parallel tests to run without directory collisions.
// Each instance automatically generates a unique path, for example:
// Instance 1: /tmp/mount_myapp_a1b2c3d4_1715631234567890123
// Instance 2: /tmp/mount_myapp_e5f6g7h8_1715631234567999999
let mut inst1 = new;
let mut inst2 = new;
inst1.mount.unwrap;
inst2.mount.unwrap; // No "Directory already exists" error!
๐ OverlayAction Reference
| Action | Behaviour |
|---|---|
Preserve |
Upper layer kept on disk; mount point removed. |
Discard |
Upper layer and mount point deleted entirely. |
Commit |
Upper merged into lower (whiteouts processed); both cleaned up. |
CommitAtomic |
Backup-and-swap merge; upper removed only after successful write. |
๐ Path Conventions
Given OverlayFS::new(PathBuf::from("/base/dir")):
| Layer | Default path | Description |
|---|---|---|
| Lower (Read-Only) | /base/dir |
The original base directory. |
| Upper (Read-Write) | /base/dir_upper |
Stores modifications (no longer a hidden dot-folder). |
| Mount Point | /tmp/mount_dir_id_ts |
Unique, collision-resistant path in the system temp folder. |
| Mount Point as Home | ~/.cache/mount_dir_id_ts |
Used if .mountpoint_as_home() is enabled. |
โ ๏ธ Configuration Rules
- ๐ Pre-mount only: You must call
set_upper(),set_inode_mode(), ormountpoint_as_home()before callingmount(). - ๐ State Protection: To prevent data corruption, these methods will panic if they detect the filesystem is already mounted.
- ๐ Automatic Cleanup: The
mount_pointdirectory is automatically created onmount()and removed onumount()or when the object is dropped.
๐ก๏ธ Safety & Error Prevention
The version 1.1.0 introduces strict state management to prevent common development errors:
-
๐ Mount State Protection
Configuration methods likeset_upper(),set_inode_mode(), andmountpoint_as_home()now check the real mount state viais_mounted(). They will panic if called while the filesystem is active to prevent configuration drift and data corruption. -
โ Collision Avoidance
The default mount point names now include a unique session ID and a nanosecond timestamp (e.g.,mount_name_session_ts). This allows multiple instances of the same application to run in parallel withoutPermission Deniedor directory conflicts. -
๐๏ธ Automatic Directory Cleanup
Whenumount()is called or theOverlayFSobject is dropped, the temporary mount point directory is automatically removed from the host system.
๐ Project Structure
src/
โโโ lib.rs # Public API re-exports
โโโ overlay.rs # OverlayFS controller, commit strategies, xattr utilities
โโโ layers.rs # LayerManager: resolve, CoW, whiteout management
โโโ inode.rs # InodeStore: thread-safe inode โ path mapping
โโโ files.rs # OverlayFiles: layer path configuration
โโโ fuse_ops.rs # FUSE operation handlers
๐ MIT License
This repository has scripts that were created to be free software. Therefore, they can be distributed and/or modified within the terms of the MIT License.
See the LICENSE file for details.
๐ฌ Contact & Support
- ๐ง Email: m10ferrari1200@gmail.com
- ๐ง Email: contatolinuxdicaspro@gmail.com