rclone serve nfs 命令详解:用 NFSv3 协议把任意云存储挂载为本地磁盘
rclone serve nfs 是 rclone 提供的一个实验性(Experimental,自 v1.65 引入)命令,它在本地或局域网内启动一个 NFSv3 服务器,将任意 rclone remote 通过标准 NFS 协议对外"服务"。文章将带你掌握该命令的安全模型、三种 NFS 文件句柄缓存机制、serve/mount 的完整实战命令,并深入源码级原理,理解它如何借助 rclone 的 VFS(虚拟文件系统)层让云对象存储表现得像一块真正的磁盘。
一、serve nfs 是什么:为什么需要它
rclone serve nfs 的核心目标是:让 rclone 的 mount 能力无需 FUSE 即可在受限平台上使用。最近版本的 macOS 安装 FUSE 非常麻烦,而 macOS 与 Linux 自带 NFS 客户端,因此 rclone 在 Unix 平台上实现了 NFSv3 服务器来"曲线救国"——NFS 协议是内核自带的协议,客户端无需额外安装驱动。
从源码看,该命令的定位非常明确。在 cmd/serve/nfs/nfs.go 的包注释中写明:
"Package nfs implements a server to serve a VFS remote over the NFSv3 protocol... This is primarily used for mounting a VFS remote in macOS, where FUSE-mounting mechanisms are usually not available."
命令的入口定义(cmd/serve/nfs/nfs.go#L142-L144)与帮助信息中亦注明:命令仅 Available on Unix platforms;在非 Unix 平台(如 Windows)会由 nfs_unsupported.go 提供占位实现。同时,该功能被标记为 status: Experimental,通过远程控制接口的 serve.AddRc("nfs", ...)(cmd/serve/nfs/nfs.go#L100-L122)可以动态创建/销毁 NFS 服务。
NFS 服务器本身基于第三方库 github.com/willscott/go-nfs 实现,真正执行网络监听与协议解析的调用位于 server.go#L62-L65 的 nfs.Serve(s.listener, s.handler)。
二、安全模型与默认监听策略(务必先读)
这个服务器没有任何认证机制。NFSv3 协议本身不提供用户认证,任何能连上端口的客户端都可以访问数据。因此文档给出的三条防护建议是:
- 只在回环(loopback)地址上运行
serve nfs; - 依赖安全隧道(如 SSH)转发;
- 或使用防火墙限制访问。
为此,命令做了两个对安全性至关重要的默认设置:
- 默认只监听
localhost:查看 server.go#L31-L34,当--addr为空时,代码会将其改写为"localhost:"; - 默认使用随机 TCP 端口:
net.Listen("tcp", "localhost:")中端口为空串意味着由操作系统随机分配一个空闲端口,只有本机能够访问。
如果想让它对局域网内的其他机器可见,必须显式指定监听地址与端口:
rclone serve nfs remote: --addr 0.0.0.0:$PORT --vfs-cache-mode=full
另外两个值得注意的行为(均有源码佐证):
--vfs-cache-mode off时挂载是只读的:NFS 写文件必须经由 VFS 缓存中转。在 server.go#L28-L30 中,若检测到CacheMode == CacheModeOff,服务器会输出警告日志"NFS writes don't work without a cache, the filesystem will be served read-only"。文档建议写入场景使用full缓存模式。- 认证 flavor 的兼容处理:在 handler.go#L67-L73 中,服务器同时通告
AUTH_NULL与AUTH_UNIX两种认证方式。注释说明:BSD 系内核的 NFS 客户端要求服务器提供AUTH_UNIX才会挂载,而 rclone 本身并不检查凭证(AUTH_UNIX 的凭据被当作不透明数据忽略),因此这只是为了客户端兼容。
三、NFS 文件句柄缓存:三种模式与核心参数
NFS 协议依赖"文件句柄(file handle)"来引用文件。rclone 的 NFS 服务器通过一个句柄缓存层将句柄映射回 VFS 路径。相关选项在 nfs.go#L29-L45 注册为全局选项(fs.RegisterGlobalOptions,可通过 --nfs-xxx 使用),并复用给 rclone nfsmount 命令(见 AddFlags 注释"for serve nfs (and nfsmount)")。
句柄缓存类型是一个枚举(nfs.go#L51-L67):
| 缓存类型 | 说明 | 数据存放 | 服务器重启后 |
|---|---|---|---|
memory(默认) |
需要新句柄时随机分配,句柄表保存在内存 | 内存 | 句柄缓存丢失,已连接的 NFS 客户端会收到 stale handle(陈旧句柄)错误 |
disk |
对对象路径做哈希,把"哈希→路径"映射写进磁盘文件 | 磁盘目录 | 可随意重启,不影响已连接客户端 |
symlink |
类似 disk,但缓存项以符号链接形式存放 |
磁盘(仅 Linux) | 不可备份/还原,因为底层文件句柄会变 |
3.1 disk 模式:路径哈希持久化
disk 缓存模式下,句柄本质上就是对象路径的 MD5 哈希。源码 cache.go#L180-L183 的 hashPath 用 md5.Sum 计算全路径;cache.go#L186-L194 的 handleToPath 再把哈希转成十六进制,并按前两位、次两位建立两级子目录存放,形如 cacheDir/ab/cd/abcdef...。句柄内容写入磁盘时保留完整路径(os.WriteFile(cachePath, []byte(fullPath), 0600),见 cache.go#L237-L239),查询时反向读取即可解析回 VFS 路径。
缓存目录的确定逻辑在 cache.go#L151-L160:
- 若指定了
--nfs-cache-dir,则使用该精确目录; - 否则自动放在
--cache-dir(或系统用户缓存区)下的serve-nfs-handle-cache-<类型>/<remote 名称编码>子目录中(remote 配置字符串会先经encoder.OS.ToStandardName转成合法目录名); - 目录权限为
0700。
正因为句柄→路径的映射被持久化到磁盘,disk 模式下 NFS 服务器重启后,客户端拿到的旧句柄依然能解析到正确路径,因此"可以随意重启而不影响已连接客户端"。
3.2 symlink 模式:Linux 专属的高性能句柄
symlink 模式是 Linux only 的高性能变体(源码文件本身带有 //go:build unix && linux 构建标签,见 symlink_cache_linux.go)。其设计在文件头注释中有清晰说明(symlink_cache_linux.go#L3-L24):
- 对象的目标路径被存为符号链接的目标,可以极大减少目录层级操作;
- 通过
name_to_handle_at()拿到缓存文件在磁盘上的句柄并直接返回给 NFS 客户端——用底层文件真实句柄作为 NFS 句柄,从而省去一次目录树查找,提升性能; - 客户端回传句柄时用
open_by_handle_at()打开,无需在目录树中搜索。
代价与限制:
- 缓存不可备份/还原:因为底层文件的句柄会随文件系统变化而失效(文件头注释第 2 点明示);
- 需要特权:
open_by_handle_at要求CAP_DAC_READ_SEARCH,因此 rclone 必须以 root 运行,或对二进制授予该能力:若权限不足,代码会在启动自检时返回sudo setcap cap_dac_read_search+ep /path/to/rcloneErrorSymlinkCacheNoPermission("symlink cache must be run as root or with CAP_DAC_READ_SEARCH",symlink_cache_linux.go#L70-L72)。启动时makeSymlinkCache()会先写入再读回一个测试 symlink 完成自检,通过后才真正启用 symlink 读写函数(symlink_cache_linux.go#L51-L88)。
3.3 --nfs-cache-handle-limit:句柄数量上限
--nfs-cache-handle-limit 控制缓存处理器最多同时缓存多少 NFS 句柄,仅对 memory 类型生效。默认值为 1000000,最小值为 5(帮助文本注明 max file handles cached simultaneously (min 5))。文档警告:该值不要设得太低,否则访问文件时可能报错;只有当服务器系统资源占用成为问题时,才考虑调低。
3.4 句柄缓存接口与子路径挂载的一致性
所有缓存类型都实现同一个 Cache 接口(cache.go#L44-L58):
ToHandle:把文件/路径变成不透明句柄;FromHandle:把句柄解析回文件系统与路径;InvalidateHandle:在重命名/删除时使句柄失效;HandleLimit:报告可安全存放的句柄数上限。
一个细节是:句柄缓存之上还包了一层 pathRewriter(cache.go#L85-L113)。它把所有子路径挂载产生的句柄统一改写为相对 VFS 根部的绝对路径,从而保证"同一个文件无论通过根挂载还是子路径挂载访问,拿到的都是同一个句柄"——这与传统 NFS 对子路径挂载的语义预期一致(子路径挂载等价于"cd 进子树")。对应的稳定性测试可见 cache_test.go#L176-L221 的 TestPathRewriterHandleStability。
四、实战:启动服务与挂载
4.1 启动 NFS 服务
对局域网提供服务:
rclone serve nfs remote: --addr 0.0.0.0:$PORT --vfs-cache-mode=full
4.2 在 Linux/macOS 上挂载
把上面的 $PORT 与运行 serve nfs 的主机地址 $HOSTNAME 填入:
mount -t nfs -o port=$PORT,mountport=$PORT,tcp $HOSTNAME:/ path/to/mountpoint
注意 NFS 协议要求同时用 port(数据)与 mountport(mount 协议)两个参数,且使用 TCP 传输。
4.3 只挂载远端的一个子目录
NFS 客户端可以把要挂载的子目录直接写进挂载路径。例如只挂载 remote 下的 photos/2024 目录:
mount -t nfs -o port=$PORT,mountport=$PORT,tcp $HOSTNAME:/photos/2024 path/to/mountpoint
源码层面对子路径挂载的处理在 handler.go#L66-L89:
- 请求的
Dirpath会被path.Clean("/" + dirpath)归一化并消除..段,确保结果始终落在 VFS 根之内(杜绝越界); - 若归一化后为
/,直接返回共享根文件系统; - 否则必须
vfs.Stat成功且该节点类型是普通目录(os.ModeDir),文件、符号链接或其他特殊节点都会以MountStatusErrNotDir拒绝; - 校验通过后返回
subFS(cleaned),一个以该目录为根的新 FS 包装。
文档特别强调了子路径挂载的两个语义:
- 子路径必须在被服务的 remote 内真实存在且是目录;
- 子路径挂载只是"挂载
/后再 cd 进去"的便捷写法:它与根挂载共享同一个底层 VFS和同一批文件句柄,因此不会把客户端与子目录的兄弟节点、父节点隔离开(没有隔离/沙箱作用)。
测试 handler_test.go#L64-L108 验证了诸如 /sub、/sub/、sub、/./sub、/foo/../sub 等各种写法都会落到 /sub;而 handler_test.go#L135+ 则验证根挂载与子路径挂载产生的句柄一致。
五、底层实现:文件系统适配层
为了把 VFS 暴露给 go-nfs 库,rclone 实现了 billy.Filesystem 接口的适配层 FS(filesystem.go#L46-L64)。它包装了一个 *vfs.VFS 与一个可选的 root 字符串(子路径挂载时非空),所有文件操作(ReadDir、Create、Open、OpenFile、Stat、Rename 等)都会先经 fullPath 拼接为 VFS 内的绝对路径再下发给 VFS。
几个对可用性至关重要的实现细节:
- 文件句柄必须有 Fileid:
setSys(filesystem.go#L28-L43)为每个FileInfo注入 UID/GID(取自 VFS 选项,默认均为 1000)以及Fileid: node.Inode()。源码注释直接警告:"without this mounting doesn't work on Linux"——缺少文件 ID,Linux 客户端将无法挂载; - statfs 信息来自 VFS:
FSStat通过h.vfs.Statfs()填充df的总容量/空闲/可用空间(handler.go#L100-L106); - 句柄失效会返回 stale 错误:当
FromHandle无法在磁盘缓存中找到句柄对应条目时,会返回NFSStatusStale(errStaleHandle,见 cache.go#L241-L243)——这正是"memory 缓存模式下重启服务器后客户端收到 stale handle 错误"的来源; - 日志级别联动:NFS 内部日志会根据 rclone 全局日志级别自动映射(
-vv对应 Trace、-v对应 Info 等,handler.go#L41-L54)。
六、VFS(虚拟文件系统):serve nfs 的基石
serve nfs 使用 rclone 的 VFS 层。云存储对象与磁盘文件差异很大——不能就地扩展、不能在中间随机写入——因此 VFS 层负责把这些对象"翻译"成更像本地磁盘的样子。理解 VFS 的各类选项是调优 serve nfs 的前提。
6.1 VFS 目录缓存(Directory Cache)
--dir-cache-time(默认 5m0s)控制目录条目在内存中被认为"新鲜"、无需向后端刷新的时长。通过 VFS 自身做的修改会立即生效或主动使缓存失效。
--dir-cache-time duration Time to cache directory entries for (default 5m0s)
--poll-interval duration Time to wait between polling for changes. Must be smaller than dir-cache-time. Only on supported remotes. Set to 0 to disable (default 1m0s)
但注意:如果改动是通过 Web 界面或其他 rclone 实例在后端直接做的,那么只有当后端支持变更轮询(polling)时才会在 --poll-interval(默认 1m)内被感知;否则只能等目录缓存过期。
两种手动刷新的方式:
- 发送
SIGHUP信号强制刷新全部目录缓存(假设只运行一个 rclone 实例):kill -SIGHUP $(pidof rclone) - 配置了 remote control(rc) 后用
rclone rc清空整个目录缓存:
或只遗忘指定文件/目录:rclone rc vfs/forgetrclone rc vfs/forget file=path/to/file dir=path/to/dir
6.2 VFS 文件缓冲(File Buffering)
--buffer-size 决定每个已打开文件在内存中预先缓冲的数据量上限。缓冲与单个打开的文件绑定、不可共享;它只在"已下载但尚未被读取"的数据上占用内存,因此它是每个打开文件的内存上限。rclone 用于缓冲的最大内存理论上可达 --buffer-size × 打开的并发文件数。
6.3 VFS 文件缓存(File Caching):四种模式
文件缓存是让 VFS 表现得像普通文件系统的关键,其四个核心参数:
--cache-dir string Directory rclone will use for caching.
--vfs-cache-mode CacheMode Cache mode off|minimal|writes|full (default off)
--vfs-cache-max-age duration Max time since last access of objects in the cache (default 1h0m0s)
--vfs-cache-max-size SizeSuffix Max total size of objects in the cache (default off)
--vfs-cache-min-free-space SizeSuffix Target minimum free space on the disk containing the cache (default off)
--vfs-cache-poll-interval duration Interval to poll the cache for stale objects (default 1m0s)
--vfs-write-back duration Time to writeback files after last use when using cache (default 5s)
缓存模式越高,rclone 的兼容性越强,代价是占用更多磁盘空间。以 -vv 运行会打印文件缓存的存放位置(在用户缓存目录,可用 --cache-dir 或环境变量控制)。
--vfs-cache-mode off(默认):读写都直接打到远端,不在磁盘缓存。因此以下操作不可用:
- 文件不能同时以读+写方式打开;
- 以写方式打开的文件不能 seek;
- 打开已存在文件并写入时必须有
O_TRUNC; - 以读方式打开但带
O_TRUNC的文件会退化为只写; - 只写打开的文件表现得如同携带
O_TRUNC; O_APPEND、O_TRUNC打开模式被忽略;- 上传失败无法重试。
--vfs-cache-mode minimal:与 off 类似,但以读+写打开的文件会先缓冲到磁盘,写文件兼容性大幅提升且磁盘占用最小。仍有限制:
- 只写打开的文件不能 seek;
- 已存在文件写打开必须有
O_TRUNC; - 只写打开忽略
O_APPEND、O_TRUNC; - 上传失败无法重试。
--vfs-cache-mode writes:只读打开仍直连远端;只写、读写都先落盘。支持所有常规文件系统操作;上传失败会以指数退避重试,最长间隔 1 分钟。
--vfs-cache-mode full(推荐用于 NFS 写入):所有读写都经磁盘缓冲(从远端读到的数据也会先落盘)。缓存中的文件是稀疏文件(sparse files),rclone 会跟踪哪些数据块已下载:应用若只读文件开头,缓存里就只会有开头的真实数据,文件在缓存中显示全尺寸但其余部分是空洞。读文件时 rclone 会预读 --buffer-size + --vfs-read-ahead 字节,前者缓冲在内存、后者缓冲在磁盘。此模式下建议 --buffer-size 不要设太大,如有需要可把 --vfs-read-ahead 调大。
IMPORTANT:并非所有文件系统都支持稀疏文件,尤其 FAT/exFAT 不支持。若缓存目录位于不支持稀疏文件的文件系统上,rclone 会性能骤降并打印 ERROR 日志。
写入回传(writeback)语义:文件只有被关闭且距最后一次访问超过 --vfs-write-back(默认 5s)后,才会写回远端。若 rclone 带着未上传的文件退出/崩溃,下次以相同 flags 启动时会补传。
缓存配额:--vfs-cache-max-size / --vfs-cache-min-free-space 可能被临时超出,原因有二:配额每 --vfs-cache-poll-interval(默认 1m)才检查一次;且打开中的文件无法被驱逐。超出配额时优先驱逐最久未被访问的文件。--vfs-cache-max-age(默认 1h)则按"距上次访问时长"逐出缓存项,时间可用 s,m,h,d,w 记法。
不要在
--vfs-cache-mode > off时用同一(或重叠的)remote 运行两个共享同一 VFS 缓存的 rclone 实例,可能造成数据损坏。规避方法是用--cache-dir为每个 rclone 分配独立缓存目录;若 remote 不重叠则无需担心。
6.4 指纹(Fingerprinting)
VFS 多处用指纹判断本地缓存副本相对远端是否变化。指纹由 size、modification time、hash(对象上可用的部分)构成。某些后端的这些属性读取很慢,例如:
hash在local、sftp后端上慢(要整文件读出再哈希);modtime在s3、swift、ftp、qingstor后端上慢(要额外 API 调用)。
--vfs-fast-fingerprint 会把这些慢操作排除出指纹,降低准确性但显著加快缓存文件的打开。若 VFS 缓存跑在 local/s3/swift 上推荐开启。注意:切换该 flag 会使缓存中文件的指纹可能失效、需要重新下载。
6.5 分块读取(Chunked Reading)
VFS 按块从远端读取文件,只请求实际被读取的块,能减少部分远端的下载配额消耗,代价是请求次数增加。相关参数:
--vfs-read-chunk-size SizeSuffix Read the source objects in chunks (default 128M)
--vfs-read-chunk-size-limit SizeSuffix Max chunk doubling size (default off)
--vfs-read-chunk-streams int The number of parallel streams to read at once
--vfs-read-chunk-streams == 0:从 --vfs-read-chunk-size 起步,每次读取块大小翻倍,直到达到 --vfs-read-chunk-size-limit(off 则无限增长)。例如以 100M 起始、limit 为 off 时按 0-100M、100M-200M、200M-300M……下载;limit 设为 500M 则变为 0-100M、100M-300M、300M-700M、700M-1200M……。把 size 设为 0/off 则禁用分块读取。这些块不会在内存中缓冲。
--vfs-read-chunk-streams > 0:并发读取固定数量的 --vfs-read-chunk-size 块,单块大小保持恒定。这对高延迟链路、或到高性能对象存储的高带宽链路有明显提速,但最佳参数需要针对后端与延迟做实验。对高性能对象存储(如 AWS S3)可从 --vfs-read-chunk-streams 16 + --vfs-read-chunk-size 4M 起步。
6.6 VFS 性能选项
S3、Swift 后端每次读取修改时间都是一次事务开销,因此 --no-modtime(或效果略异的 --use-server-modtime)对它们收益巨大:
--no-checksum Don't compare checksums on up/download.
--no-modtime Don't read/write the modification time (can speed things up).
--no-seek Don't allow seeking in files.
--read-only Only allow read-only access.
当 VFS 收到的读/写乱序时,rclone 会短暂等待(而非立即 seek):
--vfs-read-wait duration Time to wait for in-sequence read before seeking (default 20ms)
--vfs-write-wait duration Time to wait for in-sequence write before giving error (default 1s)
这些 flag 仅在不使用磁盘缓存文件时才生效。另外,使用 VFS 写缓存(writes 或 full)时,全局 --transfers(默认 4)控制缓存中已修改文件的上传并发度;注意全局 --checkers 对 VFS 无效。
--transfers int Number of file transfers to run in parallel (default 4)
6.7 符号链接(Symlinks)
VFS 默认不支持符号链接,可通过 --links(全局启用,含本地后端等原生支持场景)或 --vfs-links(仅为 VFS 层启用)开启:
--links Translate symlinks to/from regular files with a '.rclonelink' extension.
--vfs-links Translate symlinks to/from regular files with a '.rclonelink' extension for the VFS
由于多数云存储不支持真正的 symlink,rclone 将其存储为带特殊扩展名的普通文件:文件系统里显示为符号链接 link-to-file.txt 的对象,在云存储上实际存为 link-to-file.txt.rclonelink,文件内容就是链接目标路径。该方案与 local 后端的 --local-links 选项兼容。
--vfs-links 专为 rclone mount、rclone nfsmount 和 rclone serve nfs 设计,尚未在其他 serve 命令上测试。当前实现有一个限制:期望调用方自行解析子符号链接。例如对于 linked-dir -> dir 且 dir/file.txt 存在的目录树,VFS 能正确解析 linked-dir,却解析不了 linked-dir/file.txt。此外,文档记录了一个已知问题(issue #8245):当符号链接被移动到存在同名文件的目录时(反之亦然),可能产生重复文件。
6.8 大小写敏感性(Case Sensitivity)
Linux 文件系统大小写敏感;现代 Windows 大小写不敏感但保留大小写;macOS 通常大小写不敏感。
--vfs-case-insensitive 控制 rclone 的行为:
- 为
false时,文件名原样传给远端; - 为
true(或命令行不带值出现)时,rclone 会执行"fixup":如果请求的文件名精确命中则用远端现有大小写;若精确命中失败但存在仅大小写不同的文件,则透明地修正为存储的大小写。fixup 只在请求一个已存在文件时发生,新建文件的大小写敏感性由远端本身决定。
若命令行未提供该 flag,默认值取决于 rclone 运行的操作系统:Windows 与 macOS 为 true,其他平台为 false。
与之配套的 --no-unicode-normalization 控制是否对"Unicode 规范等价但编码不同"的文件名执行类似 fixup。macOS 偏好 NFD(多数平台用 NFC),因此强烈建议在 macOS 上保持默认值 false 以避免编码兼容问题。
万一目录在大小写与 Unicode 归一化后仍出现重复文件名,--vfs-block-norm-dupes 可隐藏这些重复项(并记录错误,处理方式类似 rclone sync)。代价是列目录时要扫描整个目录查重、有性能损耗,不建议默认开启;macOS 用户若远端目录同时存在 NFC/NFD 两个版本(两版都可见、都可编辑,但实际只改到 NFD 版)则可考虑开启。
6.9 磁盘统计与已用字节
--vfs-disk-space-total-size 可手动设置文件系统总空间统计(例如 256G,默认 -1),适用于自动读取不准的场景:
--vfs-disk-space-total-size Manually set the total disk space size (example: 256G, default: -1)
部分后端(最典型是 S3)不上报已用字节数。若 df 需要该信息,可加 --vfs-used-is-size:此时 rclone 不再依赖后端上报,而是像 rclone size 一样扫描整个 remote 自行计算。
WARNING:与
rclone size不同,该 flag 忽略过滤器以保证结果准确,但代价是效率极低、可能产生大量 API 调用造成额外费用。只建议作为最后手段,且仅在启用缓存时使用。
6.10 VFS 元数据(Metadata)
使用 --vfs-metadata-extension 可让 VFS 暴露内含 metadata JSON 的"元数据文件"。这些文件最初不出现于目录列表,但可被 stat 与打开;一旦被打开,就会出现在目录列表中直到目录缓存过期。注意部分后端需要配合 --metadata flag 才会创建元数据。
例如 rclone mount 配 --metadata --vfs-metadata-extension .metadata:
$ ls -l /mnt/
total 1048577
-rw-rw-r-- 1 user user 1073741824 Mar 3 16:03 1G
$ cat /mnt/1G.metadata
{
"atime": "2025-03-04T17:34:22.317069787Z",
"btime": "2025-03-03T16:03:37.708253808Z",
"gid": "1000",
"mode": "100664",
"mtime": "2025-03-03T16:03:39.640238323Z",
"uid": "1000"
}
$ ls -l /mnt/
total 1048578
-rw-rw-r-- 1 user user 1073741824 Mar 3 16:03 1G
-rw-rw-r-- 1 user user 185 Mar 3 16:03 1G.metadata
文件无元数据时返回 {},读取出错时返回 {"error":"error string"}。
元数据与 NFS 句柄的结合:当启用 --vfs-metadata-extension 且缓存类型为 disk(或 cache)时,元数据文件的句柄 = 其父文件的句柄再后缀 0x00, 0x00, 0x00, 0x01 四个字节(见 cache.go#L34-L41)。这样拿到父文件句柄即可直接推算元数据文件句柄。实现上,ToHandle 检测到路径以元数据扩展名结尾时会剥离后缀、以原始文件生成句柄后再补上 metadataSuffix(cache.go#L210-L234),反向的 FromHandle / InvalidateHandle 则会先识别并剥离该后缀。注释特别提醒:这个后缀必须是 4 字节(大端 0x00000001),因为"使用非 4 的倍数会导致 Linux NFS 客户端无法读取任何文件"(cache.go#L37-L38)。
七、命令语法与完整选项
rclone serve nfs remote:path [flags]
7.1 serve nfs 专属选项与默认值
--addr string IPaddress:Port or :Port to bind server to
--nfs-cache-dir string The directory the NFS handle cache will use if set
--nfs-cache-handle-limit int max file handles cached simultaneously (min 5) (default 1000000)
--nfs-cache-type memory|disk|symlink Type of NFS handle cache to use (default memory)
对应源码结构见 nfs.go#L69-L75 的 Options 结构体,配置键(config key)分别为 addr、nfs_cache_handle_limit、nfs_cache_type、nfs_cache_dir——这意味着它们不仅能作为命令行 flag,也能进入 --nfs-xxx 前缀的全局配置体系。
7.2 NFS 文件/目录权限与 UID/GID
--dir-perms FileMode Directory permissions (default 777)
--file-perms FileMode File permissions (default 666)
--gid uint32 Override the gid field set by the filesystem (not supported on Windows) (default 1000)
--link-perms FileMode Link permissions (default 666)
--uid uint32 Override the uid field set by the filesystem (not supported on Windows) (default 1000)
--umask FileMode Override the permission bits set by the filesystem (not supported on Windows) (default 002)
这些默认值从 VFS 公共选项流入 NFS 层的 setSys,最终注入每个文件节点的 uid/gid。
7.3 VFS 与性能选项(serve nfs 上下文)
--dir-cache-time Duration Time to cache directory entries for (default 5m0s)
--dir-perms FileMode Directory permissions (default 777)
--file-perms FileMode File permissions (default 666)
--poll-interval Duration Time to wait between polling for changes, must be smaller than dir-cache-time and only on supported remotes (set 0 to disable) (default 1m0s)
--no-checksum Don't compare checksums on up/download
--no-modtime Don't read/write the modification time (can speed things up)
--no-seek Don't allow seeking in files
--read-only Only allow read-only access
--vfs-block-norm-dupes If duplicate filenames exist in the same directory (after normalization), log an error and hide the duplicates (may have a performance cost)
--vfs-cache-max-age Duration Max time since last access of objects in the cache (default 1h0m0s)
--vfs-cache-max-size SizeSuffix Max total size of objects in the cache (default off)
--vfs-cache-min-free-space SizeSuffix Target minimum free space on the disk containing the cache (default off)
--vfs-cache-mode CacheMode Cache mode off|minimal|writes|full (default off)
--vfs-cache-poll-interval Duration Interval to poll the cache for stale objects (default 1m0s)
--vfs-case-insensitive If a file name not found, find a case insensitive match
--vfs-disk-space-total-size SizeSuffix Specify the total space of disk (default off)
--vfs-fast-fingerprint Use fast (less accurate) fingerprints for change detection
--vfs-handle-caching Duration Time to keep file handle and downloaders alive after last close (default 5s)
--vfs-links Translate symlinks to/from regular files with a '.rclonelink' extension for the VFS
--vfs-metadata-extension string Set the extension to read metadata from
--vfs-read-ahead SizeSuffix Extra read ahead over --buffer-size when using cache-mode full
--vfs-read-chunk-size SizeSuffix Read the source objects in chunks (default 128Mi)
--vfs-read-chunk-size-limit SizeSuffix If greater than --vfs-read-chunk-size, double the chunk size after each chunk read, until the limit is reached ('off' is unlimited) (default off)
--vfs-read-chunk-streams int The number of parallel streams to read at once
--vfs-read-wait Duration Time to wait for in-sequence read before seeking (default 20ms)
--vfs-refresh Refreshes the directory cache recursively in the background on start
--vfs-used-is-size rclone size Use the rclone size algorithm for Used size
--vfs-write-back Duration Time to writeback files after last use when using cache (default 5s)
--vfs-write-wait Duration Time to wait for in-sequence write before giving error (default 1s)
7.4 过滤器选项(Filter Options)
serve nfs 还继承了目录列表过滤能力,常用项如下(完整列表见命令文档):
--delete-excluded Delete files on dest excluded from sync
--exclude stringArray Exclude files matching pattern
--exclude-from stringArray Read file exclude patterns from file (use - to read from stdin)
--exclude-if-present stringArray Exclude directories if filename is present
--files-from stringArray Read list of source-file names from file (use - to read from stdin)
--files-from0 stringArray Read list of source-file names from file using NUL as separator (use - to read from stdin)
-f, --filter stringArray Add a file filtering rule
--filter-from stringArray Read file filtering patterns from a file (use - to read from stdin)
--ignore-case Ignore case in filters (case insensitive)
--include stringArray Include files matching pattern
--include-from stringArray Read file include patterns from file (use - to read from stdin)
--max-age Duration Only transfer files younger than this in s or suffix ms|s|m|h|d|w|M|y (default off)
--max-depth int If set limits the recursion depth to this (default -1)
--max-size SizeSuffix Only transfer files smaller than this in KiB or suffix B|K|M|G|T|P (default off)
--min-age Duration Only transfer files older than this in s or suffix ms|s|m|h|d|w|M|y (default off)
--min-size SizeSuffix Only transfer files bigger than this in KiB or suffix B|K|M|G|T|P (default off)
其他与命令共享的选项(含 --cache-dir、--buffer-size、--transfers 等全局 flag)可查阅全局 flags 页。
八、推荐配置速查
结合以上原理,给出三种典型场景的配置建议:
场景一:本机只读浏览远程文件(最简单、最安全)
rclone serve nfs remote: # 默认监听 localhost + 随机端口,天然只读
场景二:局域网内读写共享(开发/协作)
rclone serve nfs remote: \
--addr 0.0.0.0:2049 \
--vfs-cache-mode full \
--vfs-write-back 5s \
--nfs-cache-type disk
选择 disk 缓存类型后,即使服务器重启,已挂载的客户端句柄依然有效;在客户端执行:
mount -t nfs -o port=2049,mountport=2049,tcp $HOSTNAME:/remote /mnt/rclone
场景三:Linux 上的高性能挂载
rclone serve nfs remote: --addr 127.0.0.1:2049 --nfs-cache-type symlink --vfs-cache-mode full
前提:Linux + 以 root 运行或先执行 sudo setcap cap_dac_read_search+ep /path/to/rclone 赋予 CAP_DAC_READ_SEARCH。
九、相关阅读
- rclone serve:
serve nfs隶属于的rclone serve命令族 - rclone mount:在 macOS 上借助 NFS 免 FUSE 实现挂载的替代方案
- rclone nfsmount:共享同一套 NFS 句柄缓存选项的兄弟命令
- rc(remote control)文档:用
rclone rc vfs/forget管理目录缓存 - flags 全局选项:
--cache-dir、--buffer-size、--transfers等参数说明 - metadata 文档:VFS 元数据与
--vfs-metadata-extension的语义 - local 后端文档:
.rclonelink符号链接方案的兼容约定
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00