From 63273734633960fa6aa55ed800dd9bbc37bc96c8 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Sat, 2 May 2026 11:33:54 -0700 Subject: [PATCH] nfs --- NFS-Server.md | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/NFS-Server.md b/NFS-Server.md index 6403a35..a8582b3 100644 --- a/NFS-Server.md +++ b/NFS-Server.md @@ -115,6 +115,44 @@ sudo mount -t nfs -o nfsvers=3,nolock 127.0.0.1:/nfs /mnt/seaweedfs-nfs Binding port 111 requires root or `CAP_NET_BIND_SERVICE` and must not collide with an existing `rpcbind` on the host. +### Mount Path Resolution + +The MOUNT3 dirpath the client sends is matched against the configured +`-filer.path`: + +- **Exact match** (`:`) — mounts at the export root. +- **Subdirectory of the export** (`:/`) — the + server resolves `` in the filer and mounts the client directly + inside it. The returned filehandle encodes the subdirectory's inode, + so the client lands at `` without having to `cd` into it. One + `weed nfs` instance can therefore expose any subtree of its export + just by varying the client mount string — useful for NFS-CSI setups + where the subdirectory is encoded in `PV.spec.nfs.path`. Missing + entries return `NFS3ERR_NOENT`; non-directory entries return + `NFS3ERR_NOTDIR`. +- **Anything else** (outside the export, empty, garbage) — falls back to + the export root and logs an INFO line. This mirrors rclone's + `serve nfs` behavior so operator typos still mount somewhere + sensible rather than producing a transport-dependent split between + "empty mount" and "mount failure". + +Example with `weed nfs -filer.path=/buckets`: + +```bash +# resolves to /buckets: +mount -t nfs :/buckets /mnt +# resolves to /buckets/data (subexport mount): +mount -t nfs :/buckets/data /mnt +# fails with NFS3ERR_NOENT (under-export, missing entry): +mount -t nfs :/buckets/no-such-thing /mnt +# falls back to /buckets, with INFO log noting the typo: +mount -t nfs :/wrong/path /mnt +``` + +File-handle scoping is unchanged: handles minted by any of these mounts +still cannot escape the configured export, regardless of what the +client asked for at MOUNT time. + ## Configuration ### Command-Line Options @@ -142,7 +180,10 @@ the server ships with defensive defaults: to prevent an accidental full-namespace export. Setting `-filer.path=/` still works, but the server logs a warning because exporting the entire filer namespace with no ACLs in place is almost - never what you want. + never what you want. With `-filer.path=/`, clients can pick any + subtree at mount time via [subexport mounts](#mount-path-resolution), + but you must constrain access via `-allowedClients` or `-ip.bind` + before doing so. ### Client Allowlist