fernfs

Crates.iofernfs
lib.rsfernfs
version0.1.5
created_at2026-01-03 19:57:27.356046+00
updated_at2026-01-17 06:38:50.905681+00
descriptionA Rust NFS Server implementation
homepagehttps://github.com/lunixbochs/fernfs
repositoryhttps://github.com/lunixbochs/fernfs
max_upload_size
id2020714
size1,016,972
Ryan Hileman (lunixbochs)

documentation

https://docs.rs/fernfs

README

FernFS

License

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:

[dependencies]
fernfs = "0.0.0"
tokio = { version = "1.0", features = ["full"] }

Examples

Running the Demo File System

The demo example creates an in-memory file system with some sample files:

cargo run --example demofs

Then mount it:

Linux:

mkdir /mnt/nfs
sudo mount -o proto=tcp,port=11111,mountport=11111,nolock,addr=127.0.0.1 127.0.0.1:/ /mnt/nfs

macOS:

mkdir /mnt/nfs
sudo mount_nfs -o nolocks,vers=3,tcp,rsize=131072,port=11111,mountport=11111 localhost:/ /mnt/nfs

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:

cargo install fernfs
fernfs /path/to/directory

For local development builds:

cargo run --bin fernfs -- /path/to/directory

Command Line Options

  • -h, --host <HOST> Bind host (default: 127.0.0.1)
  • -p, --port <PORT> Bind port (default: 11111)
  • --allow-unprivileged-source-port Allow client source ports >= 1024 (default: require privileged)
  • --help Show help and exit

Creating Your Own NFS Server

To create a custom NFS server, implement the NFSFileSystem trait:

use fernfs::{tcp::NFSTcpListener, vfs::NFSFileSystem};
use async_trait::async_trait;

struct MyFileSystem {
    // Your file system state
}

#[async_trait]
impl NFSFileSystem for MyFileSystem {
    fn capabilities(&self) -> fernfs::vfs::Capabilities {
        fernfs::vfs::Capabilities::ReadWrite
    }

    fn root_dir(&self) -> u64 {
        1 // Root directory file ID
    }

    async fn lookup(&self, dirid: u64, filename: &[u8]) -> Result<u64, fernfs::nfs::nfsstat3> {
        // Implement file lookup logic
        todo!()
    }

    async fn getattr(&self, id: u64) -> Result<fernfs::nfs::fattr3, fernfs::nfs::nfsstat3> {
        // Return file attributes
        todo!()
    }

    // Implement other required methods...
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let fs = MyFileSystem::new();
    let listener = NFSTcpListener::bind("127.0.0.1:11111", fs).await?;
    listener.handle_forever().await?;
    Ok(())
}

Architecture

The library is structured into several key components:

  • vfs: Virtual File System trait that you implement for your storage backend
  • tcp: TCP server that handles client connections and protocol dispatch
  • protocol: Internal implementation of NFS, MOUNT, and PORTMAP protocols
  • xdr: 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:

  • RFC 1813: NFS Version 3 Protocol Specification
  • RFC 5531: RPC: Remote Procedure Call Protocol Specification Version 2
  • RFC 1832: XDR: External Data Representation Standard
  • RFC 1833: Binding Protocols for ONC RPC Version 2
Commit count: 92

cargo fmt