NFS File Access
ZeroFS serves the filesystem over NFSv3. macOS, Linux, and Windows can use their operating-system NFS clients.
Configure the server
Bind the NFS listener to localhost for a local mount:
[servers.nfs]
addresses = ["127.0.0.1:2049"]
Then start ZeroFS:
zerofs run --config zerofs.toml
NFS traffic is neither authenticated nor encrypted. The server trusts the numeric UID and GID supplied by the client, then applies POSIX owner, group, and mode-bit checks to that identity. A client that can reach the endpoint can assert another identity, so POSIX permissions are not a network security boundary. Bind to localhost by default; otherwise restrict the endpoint with a private network, firewall, or authenticated tunnel.
Mount the filesystem
macOS includes an NFS client. On Linux, install nfs-common on Debian/Ubuntu or nfs-utils on Fedora/RHEL if mount.nfs is absent. Windows provides an optional "Services for NFS" feature.
sudo mkdir -p /mnt/zerofs
sudo mount -t nfs \
-o vers=3,nolocks,tcp,port=2049,mountport=2049 \
127.0.0.1:/ /mnt/zerofs
Unmount with sudo umount /mnt/zerofs on macOS or Linux, or umount Z: on Windows.
Baseline mount options
| Option | Purpose |
|---|---|
vers=3 | Selects the NFS version implemented by ZeroFS. |
tcp | Uses TCP transport. |
port=2049, mountport=2049 | Directs both NFS and mount protocol requests to the ZeroFS listener. |
nolock or nolocks | Disables the separate NFS locking protocol, which ZeroFS does not implement. |
Optional client controls
The operating system supplies defaults for transfer size, caching, timeouts, and retries. Change them only for a measured problem:
| Option | Trade-off |
|---|---|
rsize=<bytes>, wsize=<bytes> | Request transfer sizes. The client and server negotiate the effective values. |
actimeo=<seconds> | Keeps attributes cached longer, reducing requests but extending the period in which another client's metadata changes may be stale. |
hard | Keeps retrying after a server or network interruption. This is normally appropriate for a writable filesystem. |
soft | Returns an I/O error after retries are exhausted. Applications must handle errors from transient stalls; do not use it as a generic performance option. |
timeo=<value>, retrans=<count> | Control retry timing. Units and exact behavior vary by operating system. |
Permissions and multiple clients
NFS sends numeric user and group IDs rather than account names. Keep UID and GID assignments consistent across clients that share files. A permission error can be diagnosed with id, ls -ln, and the mode bits on every directory in the path.
To accept remote clients, bind the listener to a private address instead of localhost:
[servers.nfs]
addresses = ["10.0.0.5:2049"]
Use that address in the mount command and restrict TCP port 2049 to the intended clients. For a custom port, set it in both addresses and the client's port and mountport options.
Mount at boot on Linux
Add an _netdev entry to /etc/fstab so boot ordering treats the mount as network storage:
127.0.0.1:/ /mnt/zerofs nfs vers=3,nolock,tcp,port=2049,mountport=2049,_netdev 0 0
Limitations
- No file-locking protocol: ZeroFS does not implement the NFS locking protocols.
fcntlbyte-range locking is available through the native kernel client, stock v9fs, andzerofs mount; applications that need locks should mount over 9P. See File locking. - Numeric identities: NFS uses numeric UIDs and GIDs, not usernames.
- Client caching: Concurrent clients may briefly observe stale attributes or data according to their mount settings.
- fsync: NFS COMMIT semantics allow fsync to return before data reaches stable storage. Over 9P, fsync returns only after data reaches stable storage.
Troubleshooting
Check the process, listener, client mount state, and kernel messages:
ps aux | grep '[z]erofs'
nc -zv 127.0.0.1 2049
mount | grep zerofs
nfsstat -c
dmesg | tail -50
For a stale file handle, unmount and remount after confirming that the server is reachable. Use mount -v to expose client-side option and negotiation errors.