文件系统内部结构(5)

为了快速访问起见,内核在内存中保存了某些数据结构。例如,如前所示,内核总是将所有文件系统的超级块保存在内存中。这主要是因为超级块保存空闲索引节点条目和空闲数据块的部分链表。因此,当操作系统创建新文件并分配新索引节点时,或是将一些新的数据块分配给现有文件时,它会先查询内存中的超级块。显然,这样速度就比较快,因为它节省了磁盘存取时间。

内核除了在内存中保存超级块之外,还保存以下数据结构:

用户文件描述符表(UFDT)

文件表(FT)

索引节点表(IT)

图13-21描述了它们之间的关系。

 

 
图13-21  文件系统运行时的数据结构

下面介绍这些数据结构。

1. 用户文件描述符表(UFDT)

UFDT是进程u区的组成部分。u区很像分配给每个进程的进程控制块(PCB)。这个UFDT有很多编号为0、1、2等的条目或插槽。这些编号被称作文件描述符(file discriptor,fd)。当打开文件时,"open"(打开)系统调用在UFDT中生成一个新的条目,并返回该值。从根本上讲,这个来自UFDT的条目就是指向文件表(FT)中条目的指针。文件打开时已经创建fd,因此对所有后续操作只要指明fd即可。fd被当作是存取UFDT中正确条目的索引,因此内核能够遍历相关的FT条目以及索引节点表(IT)条目,如图13-21所示。

如果用两种方式打开相同的文件,那么在UFDT中就有两个不同的条目,它们有两个指向FT中对应条目的描述符,这可以用图13-21中的进程A描述。注意:索引节点等于11的文件实际上是由两个进程打开的:进程A用两种方式(读、写)打开该文件,这两个模式对应于进程A的UFDT的fd分别等于4和5;而进程B打开它进行读/写,它对应进程B的UFDT的fd等于5。

因此,这些数据结构提供了共享功能。对于要由多个进程用多种方式共享使用的文件而言,在索引节点表(IT)中只有一个条目,但UFDT和FT中有多个指向该条目的条目。

记住:内核为标准输入、标准输出以及标准错误分别预留了前三个条目,它们的fd分别等于0、1、2。对每个进程都是如此,因此这三个条目出现在每个UFDT中。UFDT对进程控制很重要。当进程终止时,内核访问该进程的UFDT,逐个条目检查该UFDT,遍历FT中相关的条目,并删除这些条目。然后遍历对应的IT条目,递减"计数"字段。如果现在"计数"字段变成0,那么就从IT中删除该条目。现在,内核释放该文件占用的所有运行时I/O缓冲区和其他数据结构。即使进程执行的程序没有明确关闭文件,也要完成这样的工作。

2. 文件表(FT)

文件表(FT)是一个表格,它包含对应每个文件的一个条目以及每个进程打开文件的模式。例如,以索引节点号为11的同一个文件为例。图13-21给出了进程A同时以读模式和写模式打开该文件,而且进程B也以读/写模式打开该文件。该图说明所有指向索引节点表(IT)的核心条目(in-core entry)的三个不同的FT。

对特定文件而言,FT的主要功能就是维护特定模式下的文件偏移量。例如,该图给出了由相同进程(进程A)打开的同一个文件(其索引节点号等于11)在读模式下文件偏移量是1100,在写模式下是2000。这表明如果进程A提交"读"这个系统调用,读取这个文件中的500个字节(也就是读取其相对字节数(RBN)1100~1599),对于读操作而言,进程A的UFDT的fd等于4的FT中文件偏移量被更新为1600。如果同一个程序还提交了写300个字节的系统调用,它们就会将数据写到相对字节数2000~2299这个位置。在完成写操作后,进程A的UFDT的fd等于5的FT中文件偏移量被更新为2300。无论哪种情况,如前所述,内核完成相对字节数到逻辑块号,再到物理块号以及到最终物理地址的转换工作。

要点就是:内核难道不能在UFDT中维护这些与模式相关的文件偏移量值,从而去掉FT呢?读者会注意到:UFDT和FT之间存在着严格的一一对应关系。那么为什么FT条目不能合并到UFDT条目中呢?不这样做的主要原因是由于两个系统调用(也就是"fork"和"dup")。在fork系统调用中,进程创建子进程,并复制所有基本的数据结构,如u区。然而,在父进程和子进程之间还存在共享的一项内容。这两个进程共享使用所有打开的文件。因此,在fork系统调用后,有两个指向同一个FT条目的UFDT。此时,这两个FT条目中的计数字段就是2。shell就经常使用这个特性。

当shell运行分支程序时,它会生成新进程,然后等待新进程的终止。与此同时,新进程从标准输入读取内容,并将其写到标准输出中。shell进程和子进程共享指向标准输入和输出的读/写指针,这使得读/写指针在shell再次获取控制的时候可以准确定位。

正是由于这个原因,FT和UFDT才没有合并成一个表。

3. 索引节点表(IT)

内核预留一部分内存,用于保存索引节点表(IT)中的条目。无论何时,进程打开文件时,它在磁盘上的索引节点以及几个其他字段就会被复制到内存中。如图所示,任何时候,都有从FT指向IT的指针。如果FT中对应同一个文件有三个条目,那么所有这三个都会指向IT中唯一的一个条目。IT条目中的计数就是3。注意:这个计数是磁盘上索引节点的附加内容字段。它记录了运行时指向文件的指针数,也就是它表示运行时按照相同或不同模式打开同一个文件的进程数。

当进程关闭该文件或终止运行时,就删除由FT指向IT的那些指针,同时按照相应的数目递减IT中的计数字段。当该字段变成0的时候,IT中的索引节点条目就会被删除。因此,只有进程运行时才会用到该字段,不能将其和磁盘索引节点中的"文件链接数"或"访问计数"混淆。访问计数字段指的是不同目录中两个以上符号名调用同一个文件。即使没有进程打开它,该字段也会继续存在。

任何时候,IT中都有一些空闲条目。这些空闲条目链接在链表中,这样在打开新文件的时候,内核就可以检索出空闲条目,然后从空闲链表中删除该条目,并将它分配给新文件。当不再使用索引节点时,内核将该条目返回给IT中空闲索引节点链表。

IT的内存条目包括以下其他字段(除了磁盘上的索引节点),如表13-2所示。

表13-2  位于磁盘索引节点以外的内存IT中的附加字段

●       包含该文件的文件系统的逻辑设备号

●       索引节点号:在磁盘上索引节点中索引节点

●       号是不必要的,因为索引节点可以直接通过

●       索引节点区域的条目的相对量访问。索引节点

●       号在IT条目中是必需的,因为所有的索引节

●       点可能并没有复制到内存中

●       指针:指向IT中其他inode条目的指针

●       计数:如前所述

●       IT条目状态(锁定等)

包含该文件的文件系统的逻辑设备号

索引节点号:在磁盘上索引节点中索引节点号是不必要的,因为索引节点可以直接通过索引节点区域的条目的相对量访问。索引节点号在IT条目中是必需的,因为所有的索引节点可能并没有复制到内存中

指针:指向IT中其他inode条目的指针

计数:如前所述

IT条目状态(锁定等)

研究完文件系统的全部运行数据结构后,现在介绍系统中的一些系统调用,从而帮助读者了解整个过程。

posted @ 2012-03-17 22:44  CobbLiu  阅读(381)  评论(0编辑  收藏  举报