关于硬链接

有人可以解释我为什么内核不允许我们build立一个硬链接到一个目录。 无论是因为它打破了文件系统的有向非循环图结构的规则还是因为其他原因。 如果允许的话,还有什么其他的麻烦?

Solutions Collecting From Web of "关于硬链接"

回到第7版(或第7版)UNIX的时代,没有系统调用mkdir(2)rmdir(2)mkdir(1)程序是SUID根目录,并使用mknod(2)系统调用来创建目录,并使用link(2)系统调用来创建条目. 并在新的目录中。 link(2)系统调用只允许root做到这一点。 因此,当时(大约在1978年),超级用户有可能创建到目录的链接,但只有超级用户才允许这样做,以确保循环或其他缺失链接没有问题。 例如,如果在部分创建目录时系统崩溃,则有诊断程序来拾取碎片。


您可以在贝尔实验室找到Unix 7th Edition手册。 第2和3节没有mkdir(2)rmdir(2) 。 您使用mknod(2)系统调用来创建目录:

名称

mknod – 建立一个目录或一个特殊的文件

概要

 mknod(name, mode, addr) char *name; 

描述

Mknod创建一个新文件,其名称是由名称指向的以空字符结尾的字符串。 新文件的模式(包括目录和特殊文件位)从模式初始化。 (模式的保护部分由进程的模式掩码修改;请参阅umask(2))。 i节点的第一个块指针是从addr初始化的。 对于普通的文件和目录,addr通常是零。 在特殊文件的情况下,addr指定哪个特殊文件。

Mknod只能由超级用户调用。

也可以看看

mkdir(1),mknod(1),filsys(5)

诊断

如果文件已经被创建,则返回零; – 1如果文件已经存在,或者用户不是超级用户。

link(2)的条目指出:

诊断

链接时返回零; – 当name1找不到时返回-1; 当name2已经存在时; 当name2的目录不能被写入时; 当尝试链接到超级用户以外的用户的目录时; 当试图链接到另一个文件系统上的文件时; 当一个文件有太多的链接。

unlink(2)的条目规定:

诊断

零通常返回; – 1表示该文件不存在,无法写入其目录,或者该文件包含当前正在使用的纯过程文本。 文件本身不需要写入权限。 取消链接目录(超级用户除外)也是非法的。

ln(1)命令的手册页注意到:

禁止链接到目录或跨文件系统链接。

mkdir(1)命令的手册页注意:

目录本身的标准条目“。”,和它的父目录的“..”是自动生成的。

如果没有这些链接就不可能创建目录,这是不值得评论的。


现在, mkdir(2)rmdir(2)系统调用是标准的,允许任何用户创建和删除目录,保留正确的语义。 不再需要允许用户创建硬链接到目录。 由于引入了符号链接,这是非常真实的 – 它们不是在UNIX的第7版中,而是在很早的时候就在UNIX的BSD版本中。


使用正常的目录, ..条目明确地链接回(单独的)父目录。 如果在不同目录下的同一目录有两个硬链接(两个名称),那么..入口点在哪里? 据推测,原来的父目录 – 大概没有办法从链接的目录到达“其他”父目录。 这是一个不对称,可能会造成麻烦。 通常,如果你这样做:

 chdir("./subdir"); chdir(".."); 

(其中./subdir不是符号链接),那么你将回到你开始的目录。 如果./subdir是其他地方某个目录的硬链接,那么你将会在第二个chdir()之后的另一个目录中。 在显示chdir()操作之前和之后,您必须显示一对stat()调用。

这完全是因为允许到目录的硬链接允许目录图中的潜在循环和循环而不增加太多价值。

除了获得循环的可能性(顺便说一句,就像符号链接一样,但是这些更容易检测和处理),还有第二个我能想到的原因。

在UNIX上,许多程序都有一个常见的假设,那就是假定所有的目录都有一个链接数为2+个子目录。 这是由于POSIX标准目录条目“。” 和“..”链接到目录或它的父。

经过验证,我可以说root (/)不是例外 )。

作为递归时检测叶子目录的性能优化,这是特别有用的,但是许多应用程序将存在已经发现的其他用途

澄清通过允许“用户定义的”硬链接到目录,这些invariants如此说将不再举行,任何从属应用程序可能会停止正常工作。 令人惊讶的是,为什么你需要root权限(和一些好的设计(重新思考)),以强制创建目录硬链接

因为那么目录树将不再是目录树。 一个目录可以有多个父母。

循环引用将通过引用计数来打破垃圾回收。 维基百科描述了这个问题:

处理检测和收集参考周期的问题有多种方法。 一个是系统可能明确禁止参考周期。

这是Linux的方式。