fsid 不同
fsid 是文件系统边界的标识,是决定跨文件系统时是否自动重新mount的条件之一。举例说明:
- 服务端导出了 /a 和 /a/b 两个目录,在 /etc/exports 配置中/a指定了 crossmount 或者 /a/b 上指定了 nohide 属性,且/a与/a/b 的 fsid 不同,
- 客户端mount到了/a/b 目录,执行 lookup 请求,服务端从 /a 目录 找到 /a/b 目录时判断是否跨文件系统(nfsd_lookup_dentry->nfsd_cross_mnt),因为/a/b是导出点,且标记了/a上标记了 NFSEXP_CROSSMOUNT 或者/a/b上标记了 EX_NOHIDE 属性,所以认为这是一个跨文件系统的点,会切换 svc_export 变量,对应的 fsid 也就变了。
- 客户端收到 lookup 的返回后,会执行 nfs_lookup->nfs_fhget->nfs_attr_check_mountpoint操作,发现 lookup 的目录 /a/b 与父目录 /a 的 fsid 不同,则认为这里有一个文件系统边界,在 fattr 上标记 NFS_ATTR_FATTR_MOUNTPOINT,然后在 nfs_lookup->nfs_fhget 中将 inode 的 flag 上标记 S_AUTOMOUNT。在 nfs_lookup->d_splice_alias->d_add 中生成 inode 对应的 dentry 时,在 dentry 上标记 DCACHE_NEED_AUTOMOUNT
- 客户端后面 step into 这个/a/b 节点时,会触发 traverse_mount->__traverse_mounts 发现 DCACHE_NEED_AUTOMOUNT 标记,并执行 follow_automount->d_automount->nfs_d_automount 获取 mountpoint /a/b 的信息,并在 finish_automount 时生成新的 mount 点。
可以看到的现象是:执行 mount 命令挂载 /a 这一个目录后,cd /a/b,执行df 命令时,看到两个挂载点,分别是 /a 和 /a/b
fsid=0
在 v4版本会将这级目录当作客户端可以看到的 root 节点,举个例子:
创建 /root/test/a/b 为fsid=0,则 mount.nfs 127.0.0.1:/ 实际挂载的是服务端 /root/test/a/b 目录, mount.nfs 127.0.0.1:/c 实际挂载的是 /root/test/a/b/c 目录,但 mount.nfs 127.0.0.1:/root/test/a 依然是 /root/test/a 目录,因为它已经在根目录之外了。
fsid 相同
fsid 相同时,只有前一个生效,比如下例,a与b的fsid一样,mount b 时实际是mount fsid=1的目录,也就是a目录,虽然df显示是b目录,但实际内容是a目录