![什么是硬链接](https://linux22.com/image/224578/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A1%AC%E9%93%BE%E6%8E%A5.png)
我知道这篇文章存在: 为什么硬链接仅在同一文件系统内有效? 但不幸的是它并没有引起我的注意。
https://www.kernel.org/doc/html/latest/filesystems/ext4/directory.html 我正在阅读 Galvin 的操作系统概念,并发现了一些非常有用的资源,例如 Linux 内核文档。
文件系统中可能有许多目录条目引用相同的索引节点号——这些目录条目称为硬链接,这就是硬链接无法引用其他文件系统上的文件的原因。
作者一开始就这么说。但我不明白其背后的原因。
inode 包含的信息:
- 模式/权限(保护)
- 所有者 ID
- 组号
- 文件大小
- 文件的硬链接数量
- 上次访问时间
- 最后修改时间
- 最后修改索引节点的时间
https://www.grymoire.com/Unix/Inodes.html
既然 inode 包含这些信息,那么让硬链接引用其他文件系统上的文件有什么问题呢?
如果硬链接引用其他文件系统会出现什么问题?
关于硬链接:
“硬链接”一词具有误导性,更好的术语是“目录项”。
目录是一种文件类型,包含(至少)一对文件名和索引节点。目录中的每个条目都是“硬链接”,包括符号链接。当您创建新的“硬链接”时,您只是向某个目录添加一个新条目,该条目引用与现有目录条目相同的 inode。
这就是我如何可视化目录概念在操作系统中的样子。根据上面引用的文本,每个条目都是一个硬链接。我看到的唯一问题是多个文件系统可以具有相同范围的索引节点(但我不这么认为,因为索引节点在操作系统中受到限制)。
另外,为什么在 inode 本身中添加有关文件系统的新信息不是很好呢?那不是真的很方便吗?
答案1
“硬链接”只是文件系统层次结构中的两个(或多个)条目引用相同的底层数据结构的情况。你的图很好地说明了这一点!
就是这样;这里的所有都是它的。这就像你有一本烹饪书,末尾有索引,索引上写着“面包:参见第 3 页”和“面包店:参见第 3 页”。现在第 3 页上的内容有两个名称。
您可以根据需要拥有任意多个指向同一页面的索引条目。什么是不是工作是你有另一本书中某些内容的索引条目。另一本书根本没有存在在您当前的书中,因此引用其中的页面是行不通的,特别是因为另一本书的不同版本可能会随着时间的推移而以不同的方式编号。
因为单个文件系统只能保证自身的一致性,所以您无法像其他文件系统的 inode 一样引用“底层存储系统详细信息”,而不会一直损坏。因此,如果您想引用存储在不同文件系统上的目录条目,则必须通过路径来执行此操作。 UNIX 通过符号链接的存在来帮助您实现这一点。
我看到的唯一问题是多个文件系统可以具有相同范围的索引节点(但我不这么认为,因为索引节点在操作系统中受到限制)。
这既不真实也不合逻辑:我可以把我的硬盘寄给你,对吧。如何确保我的硬盘驱动器上的文件系统没有您计算机可能拥有的众多文件系统之一中已使用的索引节点号?
另外,为什么在 inode 本身中添加有关文件系统的新信息不是很好呢?那不是真的很方便吗?
不。将文件系统视为“存储介质上的字节”的抽象:文件系统本身就是一个独立的包含组织成文件的数据的数据结构;它不能依赖于任何外部数据来完成。破坏这一点只会导致不一致,因为独立性意味着我可以更改文件系统 A 上的 inode 编号,而不必了解文件系统 B。现在,如果 B 依赖于 A,那么它随后就会被破坏。
答案2
这个问题的挑战在于它是基于谎言。它基于这样的想法:这种事情在任何情况下都是不可能的。很容易想象这是如何运作的,因此试图解释为什么它不可能是没有用的。
您需要克服两个问题。这些问题足以阻止操作系统开发人员尝试实现它。
第一个是你如何引用哪个硬链接指向的其他文件系统。
在正在运行的操作系统中,可以为每个安装的文件系统分配一个唯一的编号。这让操作系统知道哪个挂载的文件系统负责哪个 inode。但这些数字仅在安装期间有效。如果操作系统重新启动或文件系统被卸载(移动、拔出……),则该数字可能会发生变化。
假设您可以使用文件系统的 UUID,但其可靠性值得怀疑。由于克隆和迁移,文件系统会出现重复的 UUID。
虽然这并非不可能,但这样做会导致不同文件系统的文件系统驱动程序之间的设计过度耦合,并且许多开发人员会强烈反对这样做。
第二个问题是文件系统本身需要知道一个文件上存在多少个链接。文件系统仅在没有剩余链接时删除文件。文件系统检查需要确保引用计数正确,因此需要存储外部引用计数入站。但不能保证两个文件系统始终挂载在一起以维持计数。
如果文件系统存储这些引用,保留文件而不只是删除它们,因为另一个文件系统保存了硬链接,那么当另一个文件系统被擦除或以其他方式破坏时会发生什么?
现在,您需要执行管理操作来删除它们,而无需访问外部文件系统。这确实是一个非常危险的工具。
一般来说,文件系统检查很难实现对外部链接进行审计和更正,并且由于安装一个文件系统而不是另一个文件系统而导致不匹配的情况很常见。
答案3
什么是硬链接
您混淆了索引节点和索引节点引用。硬链接是 inode 引用。
硬链接不存在,不存在这样的东西。至少不存在符号链接。每个文件至少有一个。它们只是文件参考。
你可以有一个到另一个文件系统的硬链接吗?
不
正如@MarcksMüller 所说,页码指的是本书中的一页。
是的
但这不会是同一件事:它不会是硬链接。
您可以使用符号链接。或者,有人可以实现使用 UUID/inode 编号或 UUID/文件路径链接的新文件类型。我不知道这个是否已经存在,但还没有看到它(我认为NTFS可能有它)。
关于你的问题的注释
你的图表看起来是正确的。
但是,您关于索引节点必须是唯一的断言是错误的。想象一下将 USB 连接设备从一台计算机移动到另一台计算机。它必须工作,但可能会使用与现有设备相同的索引节点号。
答案4
我并不是想回答你的问题,但是……
目录中的每个条目都是“硬链接”,包括符号链接。
那是错误的。
其实第一部分是对的。目录中的每个条目都是一个硬链接。但是,符号链接是不是目录中的条目。符号链接是文件,就像任何其他文件一样,除了其 inode 中的标志告诉操作系统,当程序尝试访问符号链接时,操作系统应特殊对待该访问。*
作者可能知道这一点,但他们试图解释硬链接,而不是符号链接,他们变得懒惰了。如果他们不那么懒惰,他们可能会说,
目录中的每个条目都是一个硬链接。就连入境为了符号链接(符号链接实际上是一种特殊类型的文件)是“硬链接”到符号链接文件。
* 当程序尝试访问符号链接时,特殊处理**是;
- 打开符号链接文件,
- 从符号链接文件中读取路径名,
- 关闭符号链接文件,
- 访问目标文件(即由从符号链接文件读取的路径名命名的文件)仿佛这是程序首先要求打开的文件。
如果目标文件是另一个符号链接,则重复该过程,直到找到非符号链接文件,或者直到找到ELOOP
错误代码被返回。
** 有一些系统调用和/或系统调用中的选项不“遵循”符号链接。这些是必要的,因为否则,任何程序(例如ls
)如何为您提供有关符号链接的信息,或者创建或销毁符号链接?