我们可以把一个磁盘分成一个或多个分区。每个分区可以包含一个文件系统(见图4-1)。
图4-1 磁盘、分区和文件系统
i节点(i-node)是固定长度的记录项,它包含有关文件的大部分信息。
如果更仔细地观察一个柱面组的i节点和数据块部分,则可以看到图4-2中所示的情况。
注意图4-2中的下列各点:
-
在图中有两个目录项指向同一i节点。每个i节点中都有一个链接计数,其值是指向该i节点的目录项数。只有当链接计数减少至0时,才可删除该文件(也就是说可以释放该文件占用的数据块)。这就是为什么“解除对一个文件的链接”操作并不总是意味着“释放该文件占用的磁盘块”的原因。这也是为什么删除一个目录项的函数被称为unlink而不是delete的原因。在stat结构中,链接计数包含在st_nlink成员中,其基本数据类型是nlink_t。这种链接类型称为硬链接。其中,POSIX.1常量LINK_MAX指定了一个文件链接数的最大值。
-
另外一种链接类型称为符号链接(symbolic link)。对于这种链接,该文件的实际内容(在数据块中)包含了该符号链接所指向的文件的名字。在下例中:
lrwxrwxrwx 1 root root 8 01-02 05:56 lib -> /usr/lib
该目录项中的文件名是3个字符的字符串lib,而在该文件中包含了8个数据字节/usr/lib。该i节点中的文件类型是S_IFLNK,于是系统知道这是一个符号链接。
- i节点包含了大多数与文件有关的信息:文件类型、文件访问权限位、文件长度和指向该文件所占用的数据块的指针等等。stat结构中的大多数信息都取自i节点。只有两项数据存放在目录项中:文件名和i节点编号。i节点编号的数据类型是ino_t。
- 每个文件系统各自对它们的i节点进行编号,因此目录项中的i节点编号数指向同一个文件系统中的相应i节点,不能使一个目录项指向另一个文件系统的i节点。这就是为什么ln(1)命令(构造一个指向一个现有文件的新目录项)不能跨越文件系统的原因。
- 当在不更换文件系统情况下为一个文件更名时,该文件的实际内容 并未移动,只需构造一个指向现有i节点的新目录项,并解除与旧目录项的链接。例如,为将文件/usr/lib/foo更名为/usr/foo,如果目录/urs/lib和/usr在同一文件系统中,则文件foo的内容无需移动。这就是mv(1)命令的通常操作方式。
我们说明了普通文件的链接计数概念,但是对于目录文件的链接计数字段又如何呢?假定我们在工作目录中构造了一个新目录:
$ mkdir testdir
图4-3显示了其结果。注意,该图显式地显示了.和..目录项。
图4-3 创建了目录testdir后的示例柱形组
对于编号为2549的i节点,其类型字段表示它是一个目录,而链接计数为2。任何一个叶目录(不包含任何其他目录的目录)的链接计数总是2,数值2来自于命名该目录(testdir)的目录项以及在该目录中的.项。对于编号为1267的节点,其类型字段表示它是一个目录,而其链接计数则大于或等于3。它大于或等于3的原因是,至少有三个目录项指向它:一个是命名它的目录项(在图4-3中没有表示出来),第二个是在该目录中的.项,第三个是在其子目录testdir中的..项。注意,父目录中的每一个子目录都会使该父目录的链接计数增1。
这种格式与UNIX文件系统的经典格式类似。
本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/。