Kernel Mount (seaweed-vfs)
seaweed-vfs is a Linux kernel filesystem client for SeaweedFS — a real
mount -t seaweedvfs mount, not FUSE. A thin kernel module handles the
filesystem while a userspace daemon (sw-kd) does the SeaweedFS networking.
Why use it over FUSE?
- Faster cached access — reads and metadata are served by the kernel, not handed off to a userspace process on every call.
- Won’t run out of memory at scale — the mount process stays small whether it exposes thousands of files or tens of millions, so it can’t OOM the way a FUSE client’s growing inode map can.
- Drop-in — a real
mountyou manage withmount,/etc/fstab, andsystemd; restart or upgrade the daemon without unmounting.
Performance
What makes it faster than a FUSE mount:
- Cached reads and metadata never leave the kernel. FUSE bounces essentially every VFS call out to a userspace process; the kernel mount calls the daemon only on a cache miss or a write — repeat reads,
stats, and directory listings come straight from the kernel’s page and dentry caches. - Kernel readahead and the page cache accelerate sequential and repeated reads, exactly like a local filesystem.
- An optional
io_uringfast path (ublk-style) keeps many requests in flight for high-concurrency workloads; the defaultread()/write()channel is the fallback. - Memory scales with available RAM, not file count. The kernel mount uses memory in proportion to what the OS can spare — reclaimable cache the kernel frees under pressure — instead of growing with the number of files in the cluster the way a FUSE client does.
Throughput and latency vary by workload and hardware — these are architectural properties, not a published benchmark. The page cache, the kernel↔daemon split, and the memory model are covered in depth in the Kernel Mount technical reference.
Requirements
- Linux, kernel 6.1 or newer (x86_64 or arm64).
- A reachable SeaweedFS filer gRPC address — the filer’s HTTP port + 10000
(default
18888), e.g.filer.example.com:18888. - One of
apt,dnf,yum, orzypper.
Install
A single command installs the kernel module and the daemon, builds the module for your running kernel (via DKMS), and — when you pass a filer — starts the daemon ready to mount:
curl -fsSL https://raw.githubusercontent.com/seaweedfs/artifactory/main/seaweed-vfs/install.sh \
| sudo FILER=filer.example.com:18888 bash
It auto-detects your package manager, architecture, and kernel. Re-run the same command any time to upgrade in place.
Mount
sudo mkdir -p /mnt/seaweed
sudo mount -t seaweedvfs filer.example.com:18888 /mnt/seaweed
Or mount automatically at boot via /etc/fstab:
none /mnt/seaweed seaweedvfs filer=filer.example.com:18888,_netdev 0 0
Then read and write /mnt/seaweed like any local directory:
ls /mnt/seaweed
df -h /mnt/seaweed
Unmount with sudo umount /mnt/seaweed.
Export over NFS (knfsd)
Experimental. A seaweedvfs mount can be re-exported to other hosts with the
standard Linux kernel NFS server (knfsd) — no separate SeaweedFS NFS gateway,
just /etc/exports. Machines without the kernel module (or a mixed fleet) then
reach the same SeaweedFS namespace over NFSv4.
What makes this safe. NFS addresses files by an opaque file handle that must keep resolving after a file moves — and must never resolve to a different object if the original is gone. seaweed-vfs guarantees both:
- A handle survives the rename of the file it names and the rename of any ancestor directory — the daemon maintains a forwarding index (O(1) work per rename, independent of subtree size) so a moved object stays reachable by its original handle, even across a daemon restart.
- A handle that can no longer be resolved returns
ESTALE— it never reads, writes, orstats another object that later took the old path. Every read, write, and attribute change carries the expected object identity, which the filer verifies atomically.
Why “experimental”: file handles are fully identity-checked, and directory
handles are generation-verified (a deleted-and-recreated directory goes stale
rather than resolving to the replacement). A few directory child operations
(readdir, and create/unlink of children) are not yet parent-generation
guarded, so a directory delete+recreate that races the cache-invalidation
window is the remaining gap.
Requirements
- The exporting host needs the kernel NFS server —
nfs-kernel-server(Debian/Ubuntu) ornfs-utils(RHEL/SUSE), providingexportfsandrpc.nfsd— in addition to the seaweedvfs mount. - Export the mount as the NFSv4 root with
fsid=0. - Multi-filer clusters need a shared filer store (an external metadata backend — SQL, Redis, Cassandra, etcd, … — that every filer points at). The rename-forwarding index lives in the filer KV; with per-filer embedded stores (leveldb/rocksdb) it is not shared, so a handle written via one filer would not resolve through another. A single-filer deployment (embedded store and all) needs nothing extra.
Example
Mount seaweedvfs, then export it:
sudo mount -t seaweedvfs filer.example.com:18888 /mnt/seaweed
# /etc/exports — fsid=0 makes the mount the NFSv4 export root
/mnt/seaweed 10.0.0.0/24(rw,fsid=0,no_subtree_check,sync)
sudo exportfs -ra
From a client:
sudo mount -t nfs4 server.example.com:/ /mnt/seaweed-nfs
Operations & reference
For pinned-kernel fleets with no compiler, Secure Boot signing, manual package install, building the module from source, and in-place upgrades, see Kernel Mount operations.