Native Kernel Client
The native client is an out-of-tree Linux module. It registers the zerofs filesystem with VFS and speaks 9P2000.L.Z over TCP or a Unix socket. Use it when ZeroFS supports your distribution and kernel channel. Use zerofs mount otherwise.
How it works
zerofs.ko connects Linux VFS and netfslib directly to the ZeroFS 9P server. Relaxed consistency uses the page cache, readahead, writeback, writable mmap, and netfslib direct I/O. The client also supports fallocate, SEEK_DATA, SEEK_HOLE, POSIX record locks, flock, and durable fsync.
| Native kernel client | zerofs mount | |
|---|---|---|
| Path | VFS and netfslib | VFS, FUSE, userspace client |
| Protocol | 9P2000.L.Z | 9P2000.L.Z |
| Install | Exact-kernel prebuilt module; root required | Included in the zerofs binary |
| Reconnect | Waits up to reconnect_grace_ms, 120 seconds by default | Waits for a server; ambiguous mutation retries stop after 120 seconds |
| HA discovery | Rotates between two configured endpoints | Probes both endpoints concurrently |
The native path avoids the /dev/fuse handoff and has lower client-side overhead. Workload and cache state determine the end-to-end difference.
Stock Linux v9fs is also supported. It needs no ZeroFS module, but uses standard 9P2000.L and does not implement the private reconnect or metadata operations. See 9P File Access.
Compatibility
Linux 6.18 is the minimum supported kernel. The target must also provide:
- x86-64 or little-endian arm64;
CONFIG_MODULES;CONFIG_NETFS_SUPPORT;CONFIG_UNIX;CONFIG_FILE_LOCKING;CONFIG_RANDSTRUCT=nandCONFIG_GCC_PLUGIN_RANDSTRUCT=n.
Packages contain modules built for one exact kernel. Supported channels are:
| Distribution | x86-64 | arm64 |
|---|---|---|
| Ubuntu 26.04, generic | repository | repository |
| Ubuntu 24.04, HWE generic | repository | repository |
| Debian 13 backports | repository | repository |
| Fedora 43 | repository | repository |
| Fedora 44 | repository | repository |
| openSUSE Tumbleweed | repository | — |
Every published target is boot-tested with a ZeroFS mount and basic I/O.
Ubuntu 24.04 packages target HWE. Server installations default to the
unsupported 6.8 GA kernel; Desktop installations track HWE. Installing
zerofs-kernel-client installs the tested HWE kernel. Reboot into it before
mounting.
Debian 13, Rocky Linux 9 and 10, and openSUSE Leap 16 ship kernels older than 6.18.
Installation
Package
The repository links in the compatibility table point to the matching
repository descriptor. Copy its URL into repo_url, then install the selector:
repo_url='https://pkgs.zerofs.net/kernel/apt/ubuntu/26.04/generic/x86_64/zerofs-kernel.list'
curl -fsSL https://pkgs.zerofs.net/zerofs.gpg \
| sudo gpg --dearmor -o /usr/share/keyrings/zerofs.gpg
curl -fsSL "$repo_url" \
| sudo tee /etc/apt/sources.list.d/zerofs-kernel.list >/dev/null
sudo apt update
sudo apt install zerofs-kernel-client
zerofs-kernel-client installs the tested kernel and its prebuilt module. Use
the same ZeroFS release on the server.
The selector prevents the channel's rolling kernel package from advancing
beyond the tested version. It loads the module when it matches the running
kernel and installs /usr/lib/modules-load.d/zerofs.conf for subsequent boots.
Source
A source build requires a kernel with CONFIG_RUST=y, its matching rust/libkernel.rmeta, kernel headers, and the compiler and bindgen versions used for that kernel. CONFIG_MODVERSIONS=y also requires Module.symvers and CONFIG_EXTENDED_MODVERSIONS=y.
cd ZeroFS/kernel
make KDIR=/lib/modules/"$(uname -r)"/build
module_path=$(make -s \
KDIR=/lib/modules/"$(uname -r)"/build module-path)
sudo install -D -m 0644 "$module_path" \
"/lib/modules/$(uname -r)/updates/zerofs/zerofs.ko"
sudo depmod -a "$(uname -r)"
printf '%s\n' zerofs | \
sudo tee /etc/modules-load.d/zerofs.conf >/dev/null
sudo modprobe zerofs
Verify the installation:
modinfo zerofs
grep zerofs /proc/filesystems
Secure Boot
Release modules are signed with the ZeroFS module key. The selector installs its public certificate at:
/usr/share/zerofs/zerofs-module-signing-cert.der
If Secure Boot rejects the module, install the distribution's mokutil
package and check whether the certificate is already enrolled:
certificate=/usr/share/zerofs/zerofs-module-signing-cert.der
mokutil --sb-state
sudo mokutil --test-key "$certificate"
If --test-key reports that it is not enrolled, request enrollment:
certificate=/usr/share/zerofs/zerofs-module-signing-cert.der
sudo mokutil --import "$certificate"
Set the one-time password requested by mokutil, then reboot. In the MOK
manager, select Enroll MOK → Continue → Yes, then enter that
password. Menu wording varies by distribution. Reboot again if prompted.
Verify the enrollment and load the module:
sudo mokutil --test-key \
/usr/share/zerofs/zerofs-module-signing-cert.der
sudo modprobe zerofs
modinfo -F signer zerofs
Enrollment is not required when Secure Boot is disabled or the certificate is
already trusted. If package installation ran before enrollment,
modules-load.d retries the module on the next boot. A module built from
source must be signed with a key trusted by that machine. MOK enrollment
requires UEFI boot through the distribution's shim and console access; other
boot chains need their own key-enrollment procedure.
Mounting
The source is an IP-literal TCP endpoint, a Unix socket, or a comma-separated HA endpoint set.
sudo mkdir -p /mnt/zerofs
sudo mount -t zerofs \
-o consistency=relaxed,msize=10485760 \
127.0.0.1:5564 /mnt/zerofs
| Option | Default | Values |
|---|---|---|
consistency=MODE | relaxed | relaxed caches metadata and data for one second and supports mmap; strict revalidates remotely and uses unbuffered I/O |
msize=N | 10485760 | 4,096 bytes through 10 MiB |
Unmount with sudo umount /mnt/zerofs.
Kernels without Rust
ZeroFS can build an x86-64 module for a compatible kernel with CONFIG_RUST=n. The release build compiles the exact kernel's Rust support and ZeroFS together, internalizes the Rust code, and runs the result through the target kernel's normal module build. The resulting module imports C kernel symbols and does not require Rust support from the running kernel.
This requires the complete configured kernel source, Module.symvers, and matching Rust and LLVM tools. Distribution headers are not enough, so this path is limited to controlled prebuilt packages. It does not support kernels older than Linux 6.18.
CI tests this path by booting an upstream Linux 6.18 kernel built with CONFIG_RUST=n.