FernFS
A complete NFSv3 server implementation in Rust that allows you to export any custom file system over the network.
Features
- Complete NFSv3 Protocol: Full implementation of all 21 procedures defined in RFC 1813
- MOUNT Protocol: Support for filesystem exports and mount operations
- PORTMAP Protocol: Service discovery support for compatibility
- Async/Await: Built on Tokio for high-performance asynchronous I/O
- Virtual File System: Clean abstraction layer for implementing custom backends
- Cross-Platform: Works on Linux, macOS, and Windows
- Standards Compliant: Follows RFC 1813 (NFSv3), RFC 5531 (RPC), and RFC 1832 (XDR)
Quick Start
Add this to your Cargo.toml:
[]
= "0.0.0"
= { = "1.0", = ["full"] }
Examples
Running the Demo File System
The demo example creates an in-memory file system with some sample files:
Then mount it:
Linux:
macOS:
Windows (Pro/Enterprise):
mount.exe -o anon,nolock,mtype=soft,fileaccess=6,casesensitive,lang=ansi,rsize=128,wsize=128,timeout=60,retry=2 \\127.0.0.1\\ X:
FernFS CLI (Mirror File System)
The fernfs binary exports an existing directory over NFS:
For local development builds:
Command Line Options
-h, --host <HOST>Bind host (default: 127.0.0.1)-p, --port <PORT>Bind port (default: 11111)--allow-unprivileged-source-portAllow client source ports >= 1024 (default: require privileged)--helpShow help and exit
Creating Your Own NFS Server
To create a custom NFS server, implement the NFSFileSystem trait:
use ;
use async_trait;
async
Architecture
The library is structured into several key components:
vfs: Virtual File System trait that you implement for your storage backendtcp: TCP server that handles client connections and protocol dispatchprotocol: Internal implementation of NFS, MOUNT, and PORTMAP protocolsxdr: XDR (External Data Representation) encoding/decoding
File System Interface
The NFSFileSystem trait provides a clean abstraction with these key concepts:
- File IDs: Every file/directory has a unique 64-bit identifier (like an inode number)
- File Handles: Opaque handles that include generation numbers for stale handle detection
- Stateless Operations: All operations are stateless and use file IDs for addressing
- Async Support: All operations are async for high performance
Standards Compliance
This implementation follows these RFCs: