FUSE Filesystem Library
A ready-to-use filesystem library based on FUSE (Filesystem in Userspace). This library provides implementations for various filesystem types and makes it easy to develop custom filesystems.
Features:
- Asynchronous I/O support
- Overlay filesystem implementation
- Passthrough filesystem support
- Easy-to-use API for custom filesystem development
Try
# run OverlayFS demo
# run PassthroughFS demo
Integration Tests (OverlayFS & PassthroughFS)
We provide an integration script that mounts overlayfs and passthroughfs examples, then runs:
- IOR for basic POSIX read/write validation.
- fio for sequential write/read and random mixed workloads.
Run Locally
Requirements: fio, ior, fuse3 (providing fusermount3), Rust toolchain.
Set WORKDIR=/custom/tmp to control temporary directory. Logs are stored under $WORKDIR/logs.
GitHub Actions
Workflow file: .github/workflows/libfuse-fs-integration.yml (runs on PR touching this crate).
Examples
Example binaries used by the integration tests:
Rootless Execution
For rootless execution of the passthrough filesystem, you need to grant the necessary capabilities to the binary:
# Build the example first
# Grant capabilities for rootless operation
This allows the passthrough filesystem to access files with elevated permissions without requiring the entire process to run as root.
UnionFS vs OverlayFS Implementation Details
This library provides both UnionFS and OverlayFS implementations with significant architectural differences:
Core Architecture Differences
UnionFS (src/unionfs/):
- Dynamic Layer System: Uses
BoxedLayer = dyn Layertrait objects for flexible layer composition - Async Trait System: Layer trait extends
ObjectSafeFilesystemwith#[async_trait]for true async operations - Context-Aware Operations: Supports
OperationContextfor UID/GID overriding during copy-up operations - Advanced Layer Methods: Implements context-aware creation methods:
create_with_context()- File creation with custom ownershipmkdir_with_context()- Directory creation with custom ownershipsymlink_with_context()- Symlink creation with custom ownershipdo_getattr_helper()- Raw metadata retrieval bypassing ID mapping
OverlayFS (src/overlayfs/):
- Static Layer System: Uses concrete
BoxedLayer = PassthroughFstype for better performance - Simpler Trait System: Layer trait extends basic
Filesystemwithout async_trait overhead - Basic Operations: Provides only fundamental overlay operations (whiteouts, opaque handling)
- Direct Passthrough: Layers are directly bound to PassthroughFs instances
Type System Comparison
| Aspect | UnionFS | OverlayFS |
|---|---|---|
| Layer Type | dyn Layer (trait object) |
PassthroughFs (concrete) |
| Trait Bounds | ObjectSafeFilesystem + async_trait |
Filesystem |
| Inode Storage | Arc<BoxedLayer> |
Arc<PassthroughFs> |
| Async Support | Full async trait methods | Standard filesystem methods |
Implementation Complexity
UnionFS Advanced Features:
// Context-aware file creation with custom UID/GID
async async
OverlayFS Simplified Approach:
// Basic layer trait with essential overlay operations
Performance vs Flexibility Trade-offs
UnionFS:
- ✅ Maximum flexibility with dynamic layer composition
- ✅ Advanced context-aware operations for complex scenarios
- ✅ True async support for better concurrency
- ❌ Higher runtime overhead due to trait objects
- ❌ More complex codebase
OverlayFS:
- ✅ Better performance with static typing
- ✅ Simpler implementation, easier to maintain
- ✅ Lower memory overhead
- ❌ Limited to PassthroughFs layers only
- ❌ Less flexibility for advanced use cases
Use Case Recommendations
-
Choose UnionFS when:
- You need custom layer implementations beyond PassthroughFs
- You require advanced copy-up with custom ownership contexts
- You need maximum flexibility for complex overlay scenarios
- Async performance is critical for your workload
-
Choose OverlayFS when:
- You only need PassthroughFs-based layers
- Performance is the primary concern
- You prefer a simpler, more maintainable codebase
- Basic overlay functionality suffices for your needs
Contributing
All commits must be signed (git commit -s) and GPG signed (-S) per project policy.