我如何获取 NFS 文件句柄并导出其完全限定路径并提取文件的属性?
How do I take an NFS file handle, and derive its fully-qualified path and extract the attributes of the file?
这开始于 a more general question in r/linux_programming,但看到那里没有回复我想问一个更基本的问题。
一旦我有了一个 NFS 文件句柄(为了讨论起见,我已经计算出即使在 NFSv4 中的易失性文件句柄下它也是一个有效的文件句柄),是否有一系列库调用来完全导出它-合格的路径? kernel documentation on just local filesystem path lookup, and an old paper on a proposed NFS path lookup scheme change 让我确信这不是我想要自己编写的代码。
通过文档和源代码,到目前为止,我怀疑代码必须位于 VFS 和 NFS 文件系统设备驱动程序代码库之一或两者之间。但我一定没有理解 VFS、NFS 和内核之间的相互关系,因为我一直无法找到如何弥合 NFS 文件句柄和我们在 shell 中习惯看到的路径之间的差距。关于用户空间中的 open(2) 调用转换为 VFS 中的 vnode,并从那里转换为 NFS 文件句柄的讨论,但我正在尝试相反的方向(因为 FS-Cache 将 NFS 文件句柄存储为正如我从阅读 NFS 源代码中得知的那样接近,而不是可以传递给 open(2)).
的路径值
与此相关的是如何获取文件属性,如所有权、权限、日期等,如果我有一个 NFS 文件句柄,并且该文件缓存在 FS-Cache 中。我想我可以获取 inode,然后以这种方式获取属性,但我试图避免必须访问 NFS 并留在 FS-Cache 中,尤其是避免对 inode 执行 find(1)。
tl;博士:nfs_fhget()
-> d_obtain_alias() -> d_absolute_path()
.
您将需要 struct vfsmount
来描述已安装的文件系统。
免责声明:此处的假设是您从 fs-cache 获得文件句柄,即它是原始 NFS 文件句柄,而不是您从 name_to_handle_at(2) 之类的东西获得的 struct fid
.
句柄来源
如果您从 handle fairy 那里得到这个 handle,即没有先前的上下文,那么客户端无法将它映射到路径。事实上,服务器可能也无法将其映射到没有 find(1)
.
的路径中
就像 inode 一样,它在文件系统中可以有多个路径,在挂载树中可以有多个该文件系统的挂载点。
但是假设您通过文件名查找获得了这个句柄,dcache 将包含指向一个 inode 的目录,其中将有一个 i_private
指向该文件句柄。 inode 还将在 i_dentry
.
中包含其缓存的目录列表
同样,挂载树可能多次挂载相同的 NFS bind-mounted。
正在查找 VFS inode
因为你有一个原始的 NFS 文件句柄,我们从 NFS 层开始,使用 nfs_fhget()
.
将文件句柄映射到 inode。
如果 inode 不在缓存中,nfs_fhget()
将只是 return 一个空白的 NFS inode。这可以通过在 fattr
参数的内容中放置一些有趣的值来检测。
fattr
有一些要求,请参阅 nfs_find_actor()。
但是一旦你成功了,你就完成了 NFS 层并且你有一个 VFS inode。
returned inode 还具有所有其他信息,如 inode 权限、所有权、日期等。
获取VFS dentry
有了 inode 后,您需要一个指向它的 dentry。
这是由 d_obtain_alias() 完成的。
与 nfs_fhget()
一样,如果缓存中没有 dentry,d_obtain_alias()
也不会失败。相反,它将创建一个“匿名 dentry”,即没有实际名称的 dentry。在这种情况下,它的名称,相对于挂载点,只是 /
.
正在将 VFS 数据结构转换为路径
假设你有 struct vfsmount
并且现在你有 dentry,你可以构建一个你有一个 struct path
.
有了 struct path
,您现在可以调用 d_absolute_path()
,最终 return 成为绝对路径。
这开始于 a more general question in r/linux_programming,但看到那里没有回复我想问一个更基本的问题。
一旦我有了一个 NFS 文件句柄(为了讨论起见,我已经计算出即使在 NFSv4 中的易失性文件句柄下它也是一个有效的文件句柄),是否有一系列库调用来完全导出它-合格的路径? kernel documentation on just local filesystem path lookup, and an old paper on a proposed NFS path lookup scheme change 让我确信这不是我想要自己编写的代码。
通过文档和源代码,到目前为止,我怀疑代码必须位于 VFS 和 NFS 文件系统设备驱动程序代码库之一或两者之间。但我一定没有理解 VFS、NFS 和内核之间的相互关系,因为我一直无法找到如何弥合 NFS 文件句柄和我们在 shell 中习惯看到的路径之间的差距。关于用户空间中的 open(2) 调用转换为 VFS 中的 vnode,并从那里转换为 NFS 文件句柄的讨论,但我正在尝试相反的方向(因为 FS-Cache 将 NFS 文件句柄存储为正如我从阅读 NFS 源代码中得知的那样接近,而不是可以传递给 open(2)).
的路径值与此相关的是如何获取文件属性,如所有权、权限、日期等,如果我有一个 NFS 文件句柄,并且该文件缓存在 FS-Cache 中。我想我可以获取 inode,然后以这种方式获取属性,但我试图避免必须访问 NFS 并留在 FS-Cache 中,尤其是避免对 inode 执行 find(1)。
tl;博士:nfs_fhget()
-> d_obtain_alias() -> d_absolute_path()
.
您将需要 struct vfsmount
来描述已安装的文件系统。
免责声明:此处的假设是您从 fs-cache 获得文件句柄,即它是原始 NFS 文件句柄,而不是您从 name_to_handle_at(2) 之类的东西获得的 struct fid
.
句柄来源
如果您从 handle fairy 那里得到这个 handle,即没有先前的上下文,那么客户端无法将它映射到路径。事实上,服务器可能也无法将其映射到没有 find(1)
.
就像 inode 一样,它在文件系统中可以有多个路径,在挂载树中可以有多个该文件系统的挂载点。
但是假设您通过文件名查找获得了这个句柄,dcache 将包含指向一个 inode 的目录,其中将有一个 i_private
指向该文件句柄。 inode 还将在 i_dentry
.
同样,挂载树可能多次挂载相同的 NFS bind-mounted。
正在查找 VFS inode
因为你有一个原始的 NFS 文件句柄,我们从 NFS 层开始,使用 nfs_fhget()
.
如果 inode 不在缓存中,nfs_fhget()
将只是 return 一个空白的 NFS inode。这可以通过在 fattr
参数的内容中放置一些有趣的值来检测。
fattr
有一些要求,请参阅 nfs_find_actor()。
但是一旦你成功了,你就完成了 NFS 层并且你有一个 VFS inode。
returned inode 还具有所有其他信息,如 inode 权限、所有权、日期等。
获取VFS dentry
有了 inode 后,您需要一个指向它的 dentry。
这是由 d_obtain_alias() 完成的。
与 nfs_fhget()
一样,如果缓存中没有 dentry,d_obtain_alias()
也不会失败。相反,它将创建一个“匿名 dentry”,即没有实际名称的 dentry。在这种情况下,它的名称,相对于挂载点,只是 /
.
正在将 VFS 数据结构转换为路径
假设你有 struct vfsmount
并且现在你有 dentry,你可以构建一个你有一个 struct path
.
有了 struct path
,您现在可以调用 d_absolute_path()
,最终 return 成为绝对路径。