Jos*_*vin 51 shell filesystems directory hard-link
我已经看到很多解释为什么基于 Unix 的操作系统中空目录的链接数是 2 而不是 1。他们都说这是因为 '.' 目录,每个目录都指向它自己。我明白为什么会有一些“。”的概念。对于指定相对路径很有用,但是在文件系统级别实现它有什么好处?为什么不让 shell 或采用路径的系统调用知道如何解释它呢?
'..' 是一个真正的链接对我来说更有意义——文件系统需要存储一个指向父目录的指针才能导航到它。但我不明白为什么“。” 成为一个真正的链接是必要的。它似乎也导致了实现中的一个丑陋的特殊情况——你会认为你只能释放链接数小于 1 的 inode 使用的空间,但如果它们是目录,你实际上需要检查一个链接数小于 2。为什么不一致?
ktf*_*ktf 37
一个有趣的问题,确实。乍一看,我看到了以下优点:
首先,您声明将 " ."解释为当前目录可以由 Shell 或系统调用完成。但是在目录中使用点条目实际上消除了这种必要性,并强制在更低级别上保持一致性。
但我不认为这是这个设计决定背后的基本思想。
在目录中创建或删除文件时,目录的修改时间戳也必须更新。此时间戳存储在其 inode 中。inode 编号存储在相应的目录条目中。
如果点条目不存在,则例程必须在父目录中此目录的条目处搜索 inode 编号,这将导致再次进行目录搜索。
但幸运的是,当前目录中有点条目。在当前目录中添加或删除文件的例程只需跳回到第一个条目(点条目通常驻留的位置)并立即找到当前目录的 inode 编号。
点输入还有第三个好处:
当fsck检查一个烂文件系统并且必须处理不在空闲列表上的非连接块时,它很容易验证数据块(当解释为目录列表时)是否有指向 inode 的点条目这反过来又指向这个数据块。如果是这样,这个数据块可能被认为是一个丢失的目录,必须重新连接。
Nor*_*ray 11
(嗯:下面的内容现在有点史诗了......)
unix 文件系统上的目录设计(迂腐,通常但不一定附加到 unix 操作系统)代表了一个很好的洞察力,这实际上减少了所需的特殊情况的数量。
“目录”实际上只是文件系统中的一个文件。文件系统中文件的所有实际内容都在inode 中(从您的问题中,我可以看到您已经知道其中的一些内容)。磁盘上的 inode 没有结构——它们只是一大堆编号的字节块,像花生酱一样散布在磁盘上。这一点用处都没有,而且对于任何有一丝整洁意识的人来说,确实是令人厌恶的。
的唯一的特殊的inode是inode编号2(不是0或1,为传统的原因); inode 2 是一个目录文件:根目录. 当系统挂载文件系统时,它“知道”它必须读取目录 inode 2 才能启动。
目录文件只是一个文件,其内部结构旨在供 opendir(3) 和朋友读取。您可以在 dir(5) 中看到其内部结构(取决于您的操作系统);如果您查看它,您将看到目录文件条目几乎不包含有关该文件的任何信息——这些信息都在文件 inode 中。该文件的少数特别之处之一是,如果您尝试使用允许写入的模式打开目录文件,则 open(2) 函数将给出错误。其他各种命令(仅举一个例子hexdump)将拒绝以正常方式处理目录文件,因为这可能不是您想要做的(但这是它们的特例,而不是文件系统的)。
一个硬链接是什么多也小于在一个目录下的文件的映射中的条目。您可以在这样的映射中有两个(或更多)条目,它们都映射到相同的 inode 编号:因此该 inode 有两个(或更多)硬链接。这也解释了为什么每个文件至少有一个“硬链接”。inode 有一个引用计数,它记录了该 inode 在文件系统某处的目录文件中被提及的次数(这是您在执行时看到的数字ls -l)。
好的:我们现在进入正题。
目录文件是字符串('filenames')到数字(inode 编号)的映射。这些 inode 编号是“在”该目录中的文件的 inode 编号。位于该目录中的文件可能包含其他目录文件,因此它们的 inode 编号将在目录中列出的编号中。因此,如果您有一个 file /tmp/foo/bar,则目录 filefoo包含一个 for 条目bar,将该字符串映射到该文件的 inode。目录文件中还有一个条目/tmp,用于foo“在”目录中的目录文件/tmp。
当您使用 mkdir(2) 创建目录时,该函数
最终结果是(几乎)唯一的特殊情况是:
st_modestat(2)。(复制自 stackoverflow 原始问题,2011-10-20)