摘要
- NFS 沿路径逐级找到文件,此后却让客户端使用服务器签发的不透明文件句柄。客户端能保存和回传句柄,却不能把其中的字节解释为 inode、磁盘位置或跨服务器通用身份。
- NFSv4 把句柄连续性分成持久与易失两类。持久句柄在对象生命期内应经受服务器重启和迁移;易失句柄可以在服务器事先声明的条件下过期。
NFS4ERR_STALE表明原对象已被删除或不再可用;NFS4ERR_FHEXPIRED则可能只表示临时引用失去连续性,对象本身仍在。恢复必须重新走一遍名字空间,而不是猜测旧字节的含义。
改了名字,未必换了文件
假设客户端通过 /team/plan 找到一份文件。管理员把它改名为 /team/archive,或者又给同一文件建立一个硬链接。名称发生了变化,底层对象却可能未变。路径记录的是当前名字空间中的走法,不能独自承担对象身份。
1989 年的 RFC 1094 已经把两者拆开。NFSv2 客户端先经独立的 MOUNT 协议取得根目录句柄,再把目录句柄与一个名字分量交给 LOOKUP,逐级换回新的句柄。随后,GETATTR、READ、WRITE 等操作携带的是句柄,而不是每次重送完整路径。
当时的文件句柄固定为 32 字节,规范明确称其为 opaque,即“不透明”。这不等于加密,也不保证它是秘密。它只规定一个知识边界:服务器可以知道如何从这些字节找到文件,客户端却无权假定里面必然是设备号、inode、表项或磁盘地址。
RFC 1813 将 NFSv3 的 nfs_fh3 改为可变长度。LOOKUP、CREATE、LINK、READDIRPLUS 等操作可以返回它;其中装入多少信息、采用什么内部构造,由服务器决定。客户端获得了可复用的引用,但服务器不必把自己的文件系统实现固化为公开接口。
相等能证明什么,不相等又不能证明什么
不透明值仍可按字节比较,但 RFC 给这种比较划了一条很窄的边界。同一服务器返回的两个句柄若相等,它们指向同一文件;若不相等,却不能据此断言它们一定是不同文件。服务器并不承诺对象与句柄字节之间是一一映射。
RFC 1813 因而把比较定位为性能优化,而非正确性依据。NFSv4 延续了这项规则。指向同一文件的硬链接理应取得相同句柄,但客户端不能反过来把每一个不同值都当成对象边界,更不能把不同服务器的句柄当作全球内容哈希来比较。
这条限制压住了缓存系统的越权冲动。缓存看见相同句柄时,可以避免重复工作;看见不同句柄时,却不能自行裁定两次操作绝不可能触及同一对象。身份映射仍由签发句柄的服务器掌握。
“持久”成为可以检查的承诺
早期 NFS 已有 stale 错误,NFSv4 则进一步规定了句柄寿命。2000 年的 RFC 3010 区分持久句柄与易失句柄,后来的 RFC 7530 和 RFC 8881 保留并细化了这套结构。
持久句柄在对象生命期内应保持不变。服务器重启不能令它自动失效;对象迁移也不应迫使客户端无缘无故接受另一个协议身份。存储可以移动,客户端无需知道内部搬迁细节,前提是服务器继续兑现同一个外部引用。
持久不等于永生。对象被删除,引用自然失去对象;文件系统不可用,服务器也无法继续兑现。此时返回 NFS4ERR_STALE。这里最重要的不是失败本身,而是旧句柄不得悄悄改指向后来占用同一内部位置的新对象。
并非所有服务器都能在所有场景维持这一不变量。分层存储、迁移机制、操作系统接口,或重启后重建的内部表,都可能让引用只能暂时成立。NFSv4 因此允许易失句柄,并要求服务器通过 fh_expire_type 告知哪些情形会让它过期。
标准给过一种示例设计:句柄包含启动时间、表槽位和代数;槽位重用后,旧代数不再匹配。但这只是实现示例,不是强制的线上格式。IETF 固定的是可观察行为,不是每台服务器内部必须使用的字段。
“失效”与“过期”保留了两种事实
NFS4ERR_STALE 说明旧引用已经无法抵达预期对象:对象已删除,或者持久句柄所属的文件系统不再可用。它在陈述引用与对象之间的关系已经断裂。
NFS4ERR_FHEXPIRED 陈述得更窄。一个易失句柄失去了连续性,可能因为解释它的表在重启中消失、代数改变,或迁移越过了它承诺的边界;底层对象却可能仍然存在。服务器拒绝旧引用,但没有捏造“文件已被删除”的结论。
若上层把两种错误都翻译成“文件不存在”,一次引用过期会被误报为数据丢失。若又把两者都当成可无限重试的短暂故障,真正删除的对象会招致无休止重试。协议没有替应用消灭不确定性,而是在最早知道事实的地方如实标出差别。
恢复是再次查找,不是修复旧身份
NFSv4 用特殊的根句柄和名字空间操作减少了对独立 MOUNT 起点的依赖。PUTROOTFH 设定当前根,连续 LOOKUP 走过各级名称。客户端若保存了路径分量,句柄过期后便可从可信根重新查找。
但这次查找是一项新观测。别人可能已经改名、删除文件,或在旧名称下创建了替代品。重走同一路径,可能找到原对象、另一个对象,也可能什么都找不到。客户端必须重新核验对象属性,以及锁、缓存和待执行操作依赖的状态。
权限同样不能混入句柄身份。有效句柄不是授权能力;服务器仍要对每项读写或修改操作独立检查访问权。重新 LOOKUP 成功,也不能自动续上旧锁,更不能证明中断的修改可以安全重放。
NFS 文件句柄的历史价值,正在于它没有被包装成万能身份。服务器控制内部映射,也必须声明连续性;协议只规定最低限度的共同规则——不透明、有限相等语义、寿命类别与诚实失败;客户端保存恢复所需的路径证据,并在连续性中断后重新验证。
路径会变而对象仍在,对象仍在而句柄已过期,句柄有效而操作仍可能无权执行。把这三句话分开,是 NFS 能够在不同文件系统之间互操作的条件。
资料来源
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
