文件系统内部结构(2)

2. 空闲块的分配

诚如前面介绍的,超级块保存一个空闲块的不完全链表。超级块要比一个数据块大。假定超级块自身包括一个1024字节的块,也就是包括256个4字节或32位的条目,每个条目对应磁盘上一个空闲块。显然,这是空闲块的不完全链表。图13-16表明超级块中编号为3、7、10、15、…、389的块空闲。该图还给出了指向最右端位置的"下一个空闲块"的指针,该指针指向编号为3的块。这表示当文件请求分配另一个块时,就可以将编号为3的块分配给它。

该链表被称作超级块缓存。如果文件请求块,内核就会从右向左检查超级块缓存以分配块。算法分配因此会很快。这个阶段,内核没必要遍历任何链表或指针。

 
(点击查看大图)图13-16  空闲块的分配

除了超级块中维护的空闲数据块链表之外,同样还要在超级块之外的磁盘上维护一些包含空闲块号的其他块。在超级块和这些块之间有链接,如图所示,这里加以简要介绍。由于编号为3、7、10等的块已经按照该顺序分配给不同的文件,所以内核还要更新超级块中指向"下一个空闲块"的指针。当分配超级块中最后一个块(也就是图13-16中编号为389的块)时,情况就不一样了。原因在于:对超级块中这个最后空闲块的分配约定完全不同。这个最后的空闲块实际上不是一个空闲块,实际上它包含接下来256个空闲块对应的256个条目。因此,当内核存取最后这个条目时,它会执行以下步骤:

① 访问并读取编号为389的块。

② 将块389回写到超级块中空闲块链表上。现在,超级块缓冲中包括编号401、410…到797的空闲块。

③ 初始化超级块中指向编号为401块的(也就是最右端的块)的"下一个空闲块"指针。

④ 将编号为389的块当作空闲块使用,将其分配给请求的文件。

⑤ 使用块389之后,内核对所有顺序请求的分配按照块号401、410…这个顺序进行,直到分配最后一个块(也就是块号为797的块)为止,分配结束。每分配一个块之后,内核更新超级块中指向"下一个空闲块"的指针。

⑥ 重复上述过程,也就是读取编号为797的块,将其存储在内存中,先分配编号为797的块,然后将编号为797的块的内容写回到超级块上。

⑦ 这会持续到所有块分配完为止。

如果文件删除一些记录,那么针对新添加的空闲块设计算法就很有意思。如果超级块可以在"空闲块列表"中放置该空闲块的块号,那么内核只要更新超级块就可以了。如果因为这个新条目的原因,超级块已经满了,那么就要将这个块的块号作为最后一个(也就是最左边的一个)维护,而且新空闲块的条目要放置在这个新分配的块中(类似于图13-16中的块号389)。该过程可以在不同层次进行。

人们比较关注该方法和用于空闲块分配的位映射法的比照情况。

15MB的磁盘需要60个大小为1KB的块,保存空闲块号。15MB的磁盘有15×1024=15 360个大小为1KB的块,因此,如果整个磁盘都没有分配,那么列表中就会有15 360个条目。大小为1KB的块可以保存256个条目。因此,为了保存空闲块号,就要有60个块,因为60×256=15 360。然而,位映射法占用15 360个位或1920字节,它比2个块还要少。相比UNIX使用的前一种方法,它占用的磁盘空间不到前者的1/30。UNIX使用该方法的优点是什么呢?主要优点就是:内核给文件分配块的速度更快。同样地,由于分配的磁盘块越来越多以及磁盘变满(也就是说,剩余的空闲磁盘块很少),这两种方法的差别也就很小了。

现在研究索引节点的结构,以及内核为文件分配空闲数据块的方法。

3. 索引节点的结构

索引节点包括以下信息:

① 所有者的用户id(uid)

② 所有者的组id (gid)

③ 保护位:诚如所知,UNIX将所有用户分成3类:所有者(Owner)、组(Group)和其他的(Others)。每一类要么有,要么没有读(r)、写(w)和执行(x)权限。因此,内核需要三个位为每类用户指明权限。因此在每个文件的索引节点中总共要用9位。

④ 文件类型:指明文件是普通文件、目录、特殊文件还是FIFO文件。

⑤ 文件访问时间:指明文件创建时间、最后一次使用该文件的时间以及最后一次改动该文件的时间。

⑥ 该文件的链接数:指明文件已知的符号名个数。只有该数为0的时候,内核才会物理删除文件(释放所有数据块以及分配给该文件的索引节点)。显然,只有在所有用户从自己目录中删除该文件时才会出现这种情况。

⑦ 文件大小

⑧ 通过多个不同索引级别分配给该文件所有块的地址。图13-17给出了它们的结构。

 
(点击查看大图)图13-17  索引节点结构

UNIX有一个在索引节点中维护数据块地址的特殊方式,这其中还有一个原因:UNIX是在研发和教育环境中而不是商业环境中设计出来的。因此,它面向的环境已经不同。在这样的环境中,成百上千个学生创建小文件,然后忘了删除这些文件,通常一个人会有大量的小文件,而在商业环境中只有一些比较大的文件。这种情况如图13-18所示。

因此,UNIX想要为使用小文件的用户提供快速处理功能,与此同时对于那些使用大文件的用户也不会造成很大的不公平。UNIX采用的一种实现方式就是减少对小文件的地址转换(Address Translation,AT)时间。其实现如下(参见图13-17)。

索引节点预留一个保存13个块编号的位置。假定1024字节的磁盘块以及需要用4个字节(或32位)表示块号,那么系统要为每个索引节点预留13×4=52个字节。除了这13个块号之外,前10个是实际分配给文件的数据块的编号。因此,如果文件大小是1024×10=10 240个字节或者更少,那么分配给该文件的所有块号可以放在索引节点中。因此,内核可以在访问索引节点的时候立刻得到这些块号。编号从0到9的这10个块被当作是图13-16中的直接块。

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