有人可以解释一下为什么内核不允许我们建立到目录的硬链接。是否因为它违反了文件系统的有向无环图结构的规则,或者是因为其他一些原因。如果它允许的话还有什么其他复杂情况?
答案 0 :(得分:17)
在第7版(或第7版)UNIX的时代,没有系统调用mkdir(2)
和rmdir(2)
。 mkdir(1)
程序是SUID root,并使用mknod(2)
系统调用来创建目录,并使用link(2)
系统调用来生成.
和..
的条目在新目录中。 link(2)
系统调用仅允许root执行此操作。因此,当时(大约1978年),超级用户可以创建指向目录的链接,但只允许超级用户这样做以确保周期或其他缺失链接没有问题。例如,如果在部分创建目录时系统崩溃,则有一些诊断程序可以拾取碎片。
您可以在Bell Labs找到Unix第7版手册。第2节和第3节没有mkdir(2)
和rmdir(2)
。您使用mknod(2)
系统调用来创建目录:
NAME
mknod - 制作目录或特殊文件
概要
mknod(name, mode, addr) char *name;
描述
Mknod创建一个新文件,其名称是由name指向的以null结尾的字符串。的模式 新文件(包括目录和特殊文件位)从模式初始化。 (保护部分 模式由进程的模式掩码修改;见umask(2))。 i节点的第一个块指针 从addr初始化。对于普通文件和目录,addr通常为零。在特殊的情况下 file,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)
系统调用是标准的,允许任何用户创建和删除目录,保留正确的语义。不再需要允许用户创建指向目录的硬链接。自从引入符号链接以来,这是双重的 - 它们不是在第7版UNIX中,而是从很早就开始使用的是BSD版本的UNIX。
对于普通目录,..
条目明确地链接回 (单个,单独)父目录。如果在不同目录中有相同目录的两个硬链接(两个名称),..
入口点在哪里?据推测,到原始父目录 - 并且可能无法从链接目录到达“其他”父目录。这是一种可能导致麻烦的不对称现象。通常情况下,如果你这样做:
chdir("./subdir");
chdir("..");
(其中./subdir
不是符号链接),然后您将返回到您开始的目录中。如果./subdir
是指向其他位置的目录的硬链接,那么您将位于与第二个chdir()
之后的目标不同的目录中。您必须在显示的stat()
操作之前和之后通过一对chdir()
来电显示。
答案 1 :(得分:6)
这完全是因为允许指向目录的硬链接允许在目录图中存在潜在的循环和循环,而不会增加太多的值。
答案 2 :(得分:4)
除了获得循环的可能性(顺便说一下,使用符号链接,但这些更易于检测和处理),我还能想到第二个原因。
在UNIX上,许多程序都使用了一个常见的假设,即假设所有目录的链接数都是2 +子目录数。这是由于POSIX标准目录条目'。'和'..'链接到目录或它的父目录。
(验证后,我可以说root
(/)不是例外。)
这对于在递归时检测叶子目录的性能优化特别有用,但是存在许多已经找到它的其他用途的应用程序
<强>澄清强>
通过允许“userdefined”硬链接到目录,这些invariants
所以说将不再成立,并且任何相关的应用程序可能会停止正常工作。
令人惊讶的是为什么你需要root权限(以及一些好的设计(重新)思考)以强制创建目录硬链接
答案 3 :(得分:3)
因为目录树将不再是目录树。一个目录可以有多个父项。
答案 4 :(得分:3)