i节点
针对驻留在文件系统上的每个文件,文件系统的i
节点表会包含一个i
节点。对i
节点的标识,采用的i
节点表中的顺序位置,以数字表示。
i
节点所维护的信息如下所示:
- 文件类型(比如,常规文件,目录,符号链接,以及字符设备等)
- 文件属主(用户ID或UID)
- 文件属组(组ID或GID)
- 3类用户的访问权限(用户,组以及其他用户)
- 3个时间戳:对文件的最后访问时间,对文件的最后修改时间,以及文件状态的最后改变时间。
- 指向文件的硬连接数量。
- 文件的大小,以字节为单位。
- 实际分配给文件的块数量。
- 指向文件数据块的指针。
ext2中的i节点和数据块指针
类似于大多数unix文件系统,ext2
文件系统在存储文件时,数据块不一定连续,甚至不一定按顺序存放。为了定位文件数据块,内核在i
节点内维护有一组指针。
无须连续存储文件块,使得文件系统对磁盘空间的利用更为高效。特别是,还能降低空闲磁盘空间的碎片化程度,即因众多不连续空闲磁盘碎片而导致的磁盘空间浪费。
目录和硬链接
在文件系统中,目录的存储方式类似于普通文件。
目录和普通文件的区别有二:
- 在其
i-node
条目中,会将目录标记为一种不同的文件类型。 - 目录是经特殊组织而成的文件。本质上是一种表格,包含文件名和
i-node
编号。
虽然一个进程能够打开一个目录,但却不能使用read()去读取目录的内容。进程同样也不能使用write()来改变一个目录的内容,仅能借助于诸如open(),link(),mkdir()之类的系统调用来间接改变其内容。
i-node表的编号始于1,而非0,因为若目录条目的i-node字段值为0,则表明该条目尚未使用。i-node 1用来记录文件系统的坏块。文件系统根目录(/)总是存储在i-node条目2中。
i-node
中存储的信息列表,会发现其中并未包含文件名,而仅通过目录列表内的一个映射来定义文件名称。其妙用在于,能够在相同或不同目录中创建多个名称,每个均指向相同的i-node
节点。这些名称成为硬链接。
可在shell
中利用ln
命令为一个已存在的文件创建新的硬连接。如下所示。
kkk@kkk-VirtualBox:~$ echo -n "hello world" > abc
kkk@kkk-VirtualBox:~$ ls -li abc
1574835 -rw-rw-r-- 1 kkk kkk 11 8月 3 16:38 abc
kkk@kkk-VirtualBox:~$ ln abc xyz
kkk@kkk-VirtualBox:~$ echo 'six degrees of separation' >> xyz
kkk@kkk-VirtualBox:~$ cat abc
hello worldsix degrees of separation
kkk@kkk-VirtualBox:~$ ls -li abc xyz
1574835 -rw-rw-r-- 2 kkk kkk 37 8月 3 16:41 abc
1574835 -rw-rw-r-- 2 kkk kkk 37 8月 3 16:41 xyz
通过ls -li
命令所示的i-node
编码(即第一列)得到了进一步证实。名称abc
和xyz
指向相同的i-node
条目,因此均指向相同的文件。ls -li
命令所示内容的第三列为对i-node
链接的计数。执行ln abc xyz
命令后,abc
所指向i-node
的链接计数升至2。
若移除其中一个文件名,另一文件名以及文件本身将继续存在。
kkk@kkk-VirtualBox:~$ rm xyz
kkk@kkk-VirtualBox:~$ ls -li abc
1574835 -rw-rw-r-- 1 kkk kkk 37 8月 3 16:41 abc
仅当i-node
的链接计数降为0时,也就是移除了文件的所有名字时,才会删除(释放)文件的i-node
记录和数据块。
总结如下:rm
命令从目录列表中删除一文件名,将相应i-node
的链接计数减1,若链接计数因此而降为0,则还将释放该文件名所指代的i-node
和数据块。
同一文件的所有名字(链接)地位平等——没有一个名字会优于其他名字。在移除与文件相关的第一个名称后,物理文件继续存在,但只能通过另一文件名来访问其内容。
在程序中如何找到与文件描述符X相关联的文件名?简单的回答是不能,至少缺乏明确而又便于移植的手段,因为一个文件描述符指向一个i-node
,而指向这个i-node
的文件名则可能有多个。
对硬链接的限制有二,均可用符号链接来加以规避。
- 因为目录条目(硬链接)对文件的指代采用了
i-node
编号,而i-node
编号的唯一性仅在一个文件系统之内才能得到保障,所以硬连接必须与其指代的文件驻留在同一文件系统中。 - 不能为目录创建硬链接,从而避免出现令系统程序陷于混乱的链接环路。
符号(软)链接
符号链接,有时也成为软连接,是一种特殊的文件类型,其数据是另一文件的名称。
在shell
中,符号链接是由ln -s
命令创建的。
符号链接的内容既可以是绝对路径,也可以是相对路径。解释相对符号链接时以链接本身的位置作为参照点。
符号链接的地位不如硬连接。尤其是,文件的链接计数中并未将符号链接计算在内。
因此,如果移除了符号链接所指向的文件名,符号链接本身还将继续存在,尽管无法再对其进行解引用操作,也将此类链接称为悬空链接。更有甚者,还可以为并不存在的文件名创建一个符号链接。
图18-2展示的情况是:两个硬连接——/home/erena/this
和/home/allyn/that
——指向同一个文件,而符号链接/home/kiran/other
,则指代文件名/home/erena/this
。
因为符号链接指代一个文件名,而非i-node
编号,所以可以用其来链接不同文件系统中的一个文件。对硬链接的那些约束也不就不会困扰到符号链接,可以为目录创建符号链接。
符号链接之间可能会形成链路。当在各个文件相关的系统调用中指定了符号链接时,内核会对一系列链接层去解引用,直到最终文件。