文件系统内部结构(1)
1. 综述
如前所示,一个磁盘可以分区从而包含多个文件系统。另外,使用mount(加挂)命令可以将一个文件系统扩展到多个物理磁盘上。从逻辑上讲,UNIX中的文件系统的布局结构如图13-14所示。读者可以认为文件系统分为4个不同的逻辑部分,如图所示。
文件系统中第一部分第0块预留给引导块。对文件系统而言,这涉及到引导过程,第一个块包括引导程序。机器加电之后,硬件自动读取包含引导程序的引导块。典型地,该引导程序包含一条读取较长引导程序的指令,或是读取UNIX内核的指令。即使磁盘上有多个文件系统,但也只有一个文件系统有这个引导块。在所有其他文件系统中,这个块是空的。
第二部分或第二个块被称作超级块。它充当文件系统头。它包括与文件系统相关的信息。任一文件系统在使用之前都要加挂到根目录上。当使用mount(加挂)命令时,文件系统的超级块被读到内核的内存中。因此,当UNIX开始运行的时候,对内核而言,所有文件系统的所有超级块在缓冲区内存中都是可用的。超级块不一定就是一个块的大小。通常它要比一个块大。"超级块"是个逻辑名称。
图13-14 文件系统的逻辑布局图 |
超级块包含的字段如表13-1所示。
表13-1 超级块的内容
● 文件系统的大小 |
● 文件系统中空闲块的数量 |
● 空闲块的部分链表 |
● 空闲链表中指向下一个空闲块的指针 |
● 索引节点链表的大小 |
● 系统中空闲索引节点的数量 |
● 空闲索引节点的部分链表 |
● 空闲链表中指向下一个空闲索引节点的指针 |
● 锁定/标识符字段 |
本书通过以下内容阐述超级块中这些字段的重要性。
文件系统中可分配的块分为两部分:第3部分和第4部分,如图13-14所示。第3部分预留给索引节点。本书已经介绍过索引节点是定长记录,它存储文件的基本信息。它很像基本文件目录(Basic File Directory,BFD)条目。索引节点包含所有者、权限、定位分配给文件的数据块地址等信息。每个文件有且只有一个索引节点。然而,不是每个索引节点只对应一个文件。例如,如果两个符号名指向某个文件,也就是说如果这两个符号名之间存在链接,那么这两个符号名只有一个索引节点,即使它们的路径名不同,因此系统中有两个对应于该文件的不同符号名,该文件也只是有一个索引节点。由于UNIX把目录当作文件,所以每个目录也有一个索引节点,根目录也是如此。
文件系统有一些预留给索引节点条目的块。这就是限制该文件系统中文件、目录和子目录数量的原因。如果文件系统中有效文件/目录很少,又要新建文件,那么在文件系统的第3部分只有少量可分配的索引节点条目。如果用户要创建新的文件,文件系统中第3部分的所有其他条目都是空闲并且可分配的。用户总是会创建比较新的文件,同时删除一些老一点的文件。因此,文件系统第1部分中空闲索引节点条目的分配是一个动态过程。因此,内核必须维护文件系统第1部分中空闲索引节点条目列表,这样当用户新建文件时,内核就可以分配该列表中的条目,然后更新该列表。该列表可以很长。通常,内核会在超级块中预留一小块空间用于保存一些空闲索引节点条目。如果这个列表很小,那么在超级块中就可以保存它。如果比较大,内核就要在超级块外面存储剩余的条目。那么这些存储在超级块外剩余的条目就被称作磁盘索引节点。
在创建文件时,内核从超级块分配一个空闲索引节点。当超级块中的空闲索引节点用完之后,查询保存在超级块之外的空闲索引节点链表。从根本上讲,超级块在这种情况下充当了"缓存"。当超级块不再包含任何空闲索引节目条目时,就用磁盘索引节点中的条目更新它,同样也要对磁盘索引节点进行适当的更新。UNIX包含为新文件分配新索引节点或是如果删除文件,释放索引节点条目并将该索引节点添加到空闲列表的算法。
例如,参考图13-15可以看到本例中文件系统有26个(0~25)索引节点。该图给出了一些空闲的或是没有分配的索引节点。超级块包含空闲索引节点的部分链表,例如25、23、21、19、17、16、15和12。链表按照从高到低的顺序维护。超级块还维护指向文件系统中下一个空闲索引节点的索引或指针。该指针在图13-15中位于索引节点17处。无论何时当用户想要创建新文件时,发生以下情况:
① 内核访问超级块。如前所述,超级块从文件系统中的第二个块开始。因此,对内核而言,访问和读取该块没有任何问题。超级块包含一个指向下一个空闲索引节点的指针。现在内核可以访问该节点。
② 内核将该索引节点分配给新文件。本例中该索引节点是17。
③ 内核更新指向下一个条目的指针,也就是在分配索引节点17后,指针现在指向图13-15中的索引节点19。
④ 当指针指明超级块中没有空闲的索引节点时,内核搜索磁盘索引节点从而找到空闲的索引节点,并更新超级块中空闲索引节点链表。同样内核还要更新指向超级块中链表最初位置的指针值,然后按照前面的步骤开始处理。
(点击查看大图)图13-15 空闲索引节点 |
文件系统中第4部分或可分配块的第二大部分包括可分配给不同文件的数据块,如图13-14所示。UNIX中并没有单元或簇的概念。按照需求,系统每次只能为文件分配一个块。分配给文件的块不必是连续的。因此,UNIX要保存分配给一个文件所有数据块的一个索引。在该文件的索引节点中可以有多个级别的索引以及数据块/索引的地址。因此,在访问文件的索引节点之后,系统就可以遍历文件的所有数据块。稍后在研究索引节点的结构中详细介绍这部分内容。
任何时候,某些数据块分配给某些文件,而其余的数据块空闲。UNIX有一个维护空闲数据块链表的有趣方式。在超级块自身中维护一个空闲数据块的部分链表。超级块还要维护一个保存在超级块中空闲数据块部分链表的指针。显然,超级块不能包含空闲数据块的全部链表。空闲数据块链表的其他条目分开保存。UNIX保存一个从超级块指向其他包含其余空闲数据块链表的块的指针。这很像保存空闲索引节点条目的方式。