4.5.3 UNIX V7文件系统

即使是早期版本的UNIX也有一个相当复杂的多用户文件系统,因为它是从MULTICS继承下来的。下面我们将会讨论V7文件系统,这是为PDP-11创建的一个文件系统,它也使得UNIX闻名于世。我们将在第10章通过Linux讨论现代UNIX的文件系统。

文件系统从根目录开始形成树状,加上链接,形成了一个有向无环图。文件名可以多达14个字符,能够容纳除了/和NUL之外的任何ASCII字符,NUL也表示成数字数值0。

UNIX目录中为每个文件保留了一项。每项都很简单,因为UNIX使用i节点,如图4-13中所示。一个目录项包含了两个域,文件名(14个字节)和i节点的编号(2个字节),如图4-33所示。这些参数决定了每个文件系统的文件数目为64K。

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

阅读 ‧ 电子书库
图 4-33 UNIX V7的目录表项

就像图4-13中的i节点一样,UNIX的i节点包含一些属性。这些属性包括文件大小、三个时间(创建时间,最后访问时间,最后修改时间)、所有者、所在组、保护信息以及一个计数(用于记录指向i节点的目录项的数量)。最后一个域是为了链接而设的。当一个新的链接加到一个i节点上,i节点里的计数就会加1。当移走一个连接时,该计数就减1。当计数为0时,就收回该i节点,并将对应的磁盘块放进空闲表。

对于特别大的文件,可以通过图4-13所示的方法来跟踪磁盘块。前10个磁盘地址是存储在i节点自身中的,所以对于小文件来说,所有必需的信息恰好是在i节点中。而当文件被打开时,i节点将被从磁盘取到内存中。对于大一些的文件,i节点内的其中一个地址是称为一次间接块(single indirect block)的磁盘块地址。这个块包含了附加的磁盘地址。如果还不够的话,在i节点中还有另一个地址,称为二次间接块(double indirect block)。它包含一个块的地址,在这个块中包含若干个一次间接块。每一个这样的一次间接块指向数百个数据块。如果这样还不够的话,可以使用三次间接块(triple indirect block)。整个情况参见图4-34。

阅读 ‧ 电子书库
图 4-34 一个UNIX的i节点

当打开某个文件时,文件系统必须要获得文件名并且定位它所在的磁盘块。让我们来看一下怎样查找路径名/usr/ast/mbox。以UNIX为例,但对所有的层次目录系统来说,这个算法是大致相同的。首先,文件系统定位根目录。在UNIX系统中,根目录的i节点存放于磁盘上固定的位置。从这个i节点,系统将可以定位根目录,虽然根目录可以放在磁盘上的任何位置,但假定它放在磁盘块1的位置。

接下来,系统读根目录并且在根目录中查找路径的第一个分量usr,以获取/usr目录的i节点号。由i节点号来定位i节点是很直接的,因为每个i节点在磁盘上都有固定的位置。根据这个i节点,系统定位/usr目录并在其中查找下一个分量ast。一旦找到ast的项,便找到了/usr/ast目录的i节点。依据这个i节点,可以定位该目录并在其中查找mbox。然后,这个文件的i节点被读入内存,并且在文件关闭之前会一直保留在内存中。图4-35显示了查找的过程。

阅读 ‧ 电子书库
图 4-35 查找/usr/ast/mbox的过程

相对路径名的查找同绝对路径的查找方法相同,只不过是从当前工作目录开始查找而不是从根目录开始。每个目录都有.和..项,它们是在目录创建的时候同时创建的。.表项是当前目录的i节点号,而..表项是父目录(上一层目录)的i节点号。这样,查找../dick/prog.c的过程就成为在工作目录中查找..,寻找父目录的i节点号,并查询dick目录。不需要专门的机制处理这些名字。目录系统只要把这些名字看作普通的ASCII字符串即可,如同其他的名字一样。这里惟一的巧妙之处是..在根目录中指向自身。