原文链接:
Exporting
所有的文件系统操作都需要一个dentry(或者两个)作为起始点。本地应用程序通过打开的文件描述符或 cwd/root 对合适的 dentry 进行引用计数保留。然而,通过远程文件系统协议(如 NFS)访问文件系统的远程应用程序可能无法保存这样的引用,因此需要一种不同的方式来引用特定的 dentry。由于替代的引用形式需要在重命名、截断和服务器重启时保持稳定(除其他外,尽管这些往往是最有问题的),因此没有像“文件名”这样的简单答案。
此处讨论的机制允许每个文件系统实现指定如何为任何 dentry 生成不透明(文件系统之外)字节字符串,以及如何为任何给定的不透明字节字符串找到合适的 dentry。
这个字节串将被称为“文件句柄片段”,因为它对应于 NFS 文件句柄的一部分。
支持文件句柄片段和 dentries 之间映射的文件系统将被称为“可导出”。
dcache 通常包含任何给定文件系统树的适当前缀。 这意味着如果任何文件系统对象在 dcache 中,那么该文件系统对象的所有祖先也在 dcache 中。 由于正常访问是通过文件名,这个前缀是自然创建的并且很容易维护(通过每个对象在其父对象上维护一个引用计数)。
但是,当通过解释文件句柄片段将对象包含到 dcache 中时,不会自动为对象创建路径前缀。 这导致了dcache两个相关但不同的功能,而这是正常访问文件系统所不需要的。
为了实现这额功能,dcache需要:
对一个需要可导出的文件系统,它必须:
return d_splice_alias(inode, dentry);
来结束。 文件系统实现通过在 struct super_block
中设置 s_export_op
字段来声明文件系统的实例是可导出的。 此字段必须指向具有以下成员的“struct export_operations”结构:
encode_fh (可选)
获取一个 dentry 并创建一个文件句柄片段,稍后可用于为同一对象查找或创建一个 dentry。默认实现会创建一个文件句柄片段,该片段会根据 32 位 inode 和已编码的 inode 的生成编号进行编码,并在必要时为父级提供相同的信息。
fh_to_dentry (必选)
给定一个文件句柄片段,这应该找到隐含的对象并为其创建一个 dentry(可能使用 d_obtain_alias)。
fh_to_parent (可选但强烈推荐)
给定一个文件句柄片段,这应该找到隐含对象的父级并为其创建一个 dentry(可能使用 d_obtain_alias)。 如果文件句柄片段太小,可能会失败。
get_parent (可选但强烈推荐)
当给定一个目录的 dentry 时,这应该返回父目录的 dentry。 很可能父 dentry 已由 d_alloc_anon 分配。 默认的 get_parent 函数只返回一个错误,因此任何需要查找父级的文件句柄查找都将失败。
->lookup("…") 不用作默认值,因为它可以在 dcache 中留下“…”条目,这些条目太混乱而无法使用。
get_name (可选)
当给定一个父 dentry 和一个子 dentry 时,这应该在由父 dentry 标识的目录中找到一个名称,这会找到由子 dentry 标识的对象。 如果未提供 get_name 函数,则提供默认实现,该实现使用 vfs_readdir 查找潜在名称,并匹配 inode 编号以查找正确匹配项。
文件句柄片段由 1 个或多个 4 字节字的数组以及一个 1 字节的“类型”组成。
decode_fh 例程不应依赖于传递给它的规定大小。 这个大小可能比encode_fh 生成的原始文件句柄大,在这种情况下,它将用空值填充。 相反,encode_fh 例程应该选择一个“类型”,它指示 decode_fh 文件句柄有多少是有效的,以及应该如何解释它。