6.2.8 UNIX文件系统概要

1.UNIX文件分类

(1)普通文件

普通文件是以字节为单位的数据流类型的文件,如文本文件、源程序、数据文件、二进制文件等。

(2)目录文件

将文件目录当做一种特殊的文件,即目录文件。目录文件中包含若干个目录项,UNIX系统中,目录项只包括文件名和索引节点号,通常将目录项中的信息放在一个称为索引节点(i节点)的结构中,一是便于文件共享,即不同的用户可通过不同文件路径名共享一个文件;二是加快文件检索的速度。

每创建一个文件,就有一个唯一索引号与其对应。与Windows操作系统不同,UNIX的目录树形结构只有一个根节点。

(3)特殊文件

将硬件设备当做特殊文件,即设备文件。又分为两类:块设备和字符设备。块设备以字节块为处理单位,如磁盘、磁带等;字符设备是以字符为处理单位,如显示器、打印机、键盘等。

(4)管道文件

UNIX中管道线就是一个连接两个进程的一个打开文件。管道文件是提供进程通信的一种机制,由特定原语实现。UNIX系统将管道文件作为通信介质,构成两端进程传递信息的流水线。通常设定一个进程向管道中写信息,另一个进程从管道中读信息。

管道包括无名管道(pipe)和有名管道(FIFO管道或称命名管道)。无名管道是一种临时文件,用于父子进程或兄弟进程之间的通信,没有文件路径名,不占用文件目录项,依附进程临时存在,当进程终止,无名管道也随之消亡。有名管道用于不同用户进程间的通信,它具有普通的UNIX系统文件名。在系统中可利用MKNOD命令建立永久的管道,除非刻意删除它,否则它将一直保持在系统中。另外,只要事先约定某一特定文件名,所有知道该约定的服务进程,都可以方便地利用管道进行通信。

(5)链接文件

链接文件是一类特殊的文件,称为符号链接或软链接。链接文件包含了另一个文件的路径名。路径可以是任意文件或目录,可以链接不同文件系统的文件。当对链接文件读写时,系统自动将该操作转换为对源文件的操作,但删除链接文件时,系统仅删除链接文件,而不删除源文件本身。

2.UNIX文件系统的组织

UNIX文件系统主要分为两大类:根文件系统和子文件系统。根文件系统是UNIX系统至少应该含有的一个文件系统,它包含了保证系统正常运行的操作系统代码和目录等,由“/”符号来表示。根文件系统一旦安装上,在整个系统运行过程中是不能卸载的。子文件系统可以是多个,根据需要动态安装到根文件系统中才能使用。多个子文件系统并列或串连安装(mount)到根文件系统的某个目录下。经过安装后,根文件系统与子文件系统构成了一个完整目录层次结构、容量更大的文件系统。已安装的子文件系统也可以从整个文件系统中卸载(unmount)下来,回复安装前的独立状态。

UNIX文件系统通常是按照文件卷(或称逻辑卷)的方式进行构造的。这种文件卷称为文件系统。

(1)物理卷、逻辑卷、卷组

每一个独立的硬盘就是一个物理卷。在物理卷中可划分大小相同的磁盘块。每个物理卷在系统中占有唯一的逻辑名称,这些名称的描述存放在/dev目录下,如,/dev/hdisk0是系统中的第一个硬盘,/dev/hdisk1是系统中的第二个硬盘。

卷组可由一个或多个物理卷组成。在每个卷组中可以定义一个或多个逻辑卷。逻辑卷是位于物理卷上的信息组合,可看做是多个物理卷中部分磁盘块的集合,也可看成是一个卷组内多个逻辑分区的集合。在逻辑卷上的数据可以连续或者不连续地出现在物理卷中。逻辑卷可扩展,且可以跨越卷组内的多个物理卷。

(2)UNIX文件系统的存储结构

其结构由4部分组成:引导块、超级块、索引节点表、数据区,如图6-9所示。

6.2.8 UNIX文件系统概要 - 图1

图 6-9 UNIX文件系统的存储结构

0#块一般用于系统引导或空闲;1#块为超级块,用于存放文件系统的资源管理信息,如整个文件系统的盘块数、磁盘索引节点的盘块数、空闲盘块号表及指向下一个空闲盘块号指针、空闲索引节点表和指向下一个空闲索引节点的指针等;从第2#至K#块存放磁盘索引节点;第K+1#及其后续各块存放文件数据及目录文件数据等。

(3)目录文件的数据结构

DOS、Windows操作系统中,将目录文件设计成一个数据结构,即文件的索引信息表,包括了文件的文件名、大小、类型、修改日期等许多属性信息;而在UNIX系统中,则分为目录文件、索引节点表两个数据结构,如图6-10所示。

6.2.8 UNIX文件系统概要 - 图2

图 6-10 UNIX目录文件的数据结构

3.空闲盘块的分配与回收

UNIX系统采用成组链接法对空闲盘块加以组织。通常是将每100个空闲盘块划归一个组,将每组中的所有盘块号,存放在其前一组的第一个空闲盘块号指示的盘块中,即每一组的第一个空闲块中登记下一组空闲块的块号和空闲块数,余下的空闲块的块号及块数登记在一个专用块中。将第一组中的所有空闲的盘块号,放入超级块的空闲盘块号表中。

系统初始化时先将专用块内容读到内存,需要分配空闲块时,在内存中找到相应的空闲块,每分配一块,将空闲块数减1。在将一组中的第一个空闲块分配出去之前,需要将登记在该块中的下一组的块号及块数保存到专用块中。

当一组空闲块被分配完后,将专用块的内容读到内存,指出另一组可供分配的空闲块。当回收一块时,将回收块的块号登记到当前组中,并将空闲块数加1。如果当前组已满100块,则将内存中的内容写到回收的那块中,该回收块作为新组的第一块。

采用成组连接后,分配回收磁盘块时均在内存中查找和修改,只是在一组空闲块分配完,或空闲的磁盘块构成一组时才启动磁盘读写。比单块连接方式效率高。

4.文件的物理结构与寻址方式

UNIX文件系统采用的是多级索引结构。从逻辑结构上讲,UNIX的文件是流式文件。从物理结构上讲,UNIX的文件是以索引方式存放的,索引可以是一级、二级、三级索引。

在UNIX系统中,文件数据存储在离散的磁盘块中,假设,UNIX的每个文件索引节点有13项,文件的物理块号直接或间接地存放在该文件索引节点的13个地址项中。文件索引节点的13个地址项就是13个指针,每个指针长度为4个字节。查找文件时,只需找到该文件的索引节点,便可以通过直接或间接寻址方式获得指定文件的物理块号。

(1)寻址方式

1)直接寻址。若文件大小在10KB以内时,采用前10项直接寻址,即用前10个指针直接访问文件,这种分配方式称为直接寻址或直接索引。

2)一次间接寻址。当文件物理块数目大于等于10且小于266时,采用一次间接寻址方式。利用第11项指向一个索引块,该索引块中存放了可分配给文件直接存储数据的物理块的索引项(或指针)。假设物理块大小为1KB,则每个物理块中可以存放256个索引项。这种分配方式称为一次间接寻址或一级间接索引。这样可将寻址范围由10KB扩大到266KB。

3)多次间接寻址。对于更大的文件还可利用第12项作为二次间接寻址,或第13项作为三次间接寻址。二次间接寻址可将寻址范围扩大到64MB。三次间接寻址可将寻址范围扩大到16GB。

(2)地址转换

UNIX系统利用地址转换过程将文件的字节偏移量转换为文件的物理块号。这一转换过程分两步实现:

第一步将偏移量转化为文件逻辑块号。在UNIX系统中,被打开的文件在文件表项中有一个读写指针,用以指示下次要读写的字符位置。该偏移量是从文件第一个字符位置开始计算的。在每次读写时,都要先把字节偏移量转换为文件逻辑块号和块内位移量。其转换方法是:将字节偏移量除以盘块大小的字节数,其商是文件逻辑块号,余数是块内位移量。

第二步将逻辑块号转换为物理盘块号。根据逻辑盘块号可知对应的文件地址是直接地址还是间接地址,不同的地址应采用不同的转换方法。

1)文件地址是直接地址时,将文件逻辑块号转换为索引节点的地址项下标,从该地址项中即可获得物理盘块号。

2)文件地址是间接地址时,对于一次间接寻址,可按下述步骤进行转换:从索引节点的一次间接项中得到一次间接的盘块号;调用系统内部过程读入间接块的内容;计算一次间接块中的地址下标,即将文件的逻辑块号减10;从相应下标的地址项中得到物理块号。对于多次间接寻址,其转换方法与一次间接寻址类似,但要多次循环。

5.支持文件存取的用户文件描述符表和文件表

(1)用户文件描述符表

文件描述符是一非负整数,内核以此来标志一个特定进程正在操作的文件。每当打开文件或创建新文件时,内核将向进程返回一个文件描述符(File Descriptor,FD)供读写文件用。对于进程而言,内核会在每个进程空间中维护一个文件描述符表,或者说,在每个进程PCB的U区中设置了一张用户文件描述符表。当初次打开文件访问时,便在用户文件描述符表中分配一个空表项,取该表项在表中的偏移量,作为文件描述符返回给用户。以后再访问该文件时,只需提供该文件的描述符,系统根据描述符便可找到相应文件的内存索引节点。

(2)文件表

系统设置了读写指针,便于对文件进行读、写操作。在UNIX系统中引入了文件表,用户进程的一次文件存取在文件表中有一个对应表项,文件表项中存放文件的读、写指针等相关信息。

6.索引节点的管理

(1)索引节点

为了加速对文件目录的查找,在UNIX系统中,将文件名和文件说明分开,由文件说明形成一个称为索引节点的数据结构,而相应的文件目录项则只由文件名和对应的索引节点号构成,这样大大减小了系统各级目录的规模。UNIX系统中的每个目录项通常占16个字节,其中,文件名占14个字节,索引节点号占2个字节。文件的类型、长度、所有者、文件所在的磁盘块号等信息都存放在索引节点中。索引节点是文件系统的核心内容,也是UNIX内核最重要的数据结构。分为磁盘索引节点和内存索引节点两种。

1)磁盘索引节点。索引节点以表目形式存放在磁盘上,故又称为磁盘索引节点。磁盘索引节点是一个数据结构,其中存放文件的说明信息。每个文件都有唯一的一个磁盘索引节点,记录了文件属主标志符、文件类型、文件存取权限、文件物理地址、文件长度、文件链接计数、文件存取时间等。

2)内存索引节点。为了加快文件的存取速度和减轻磁盘I/O的压力,专门在内存中建立了一个内存索引节点。当文件被打开时,磁盘索引节点的内容被复制到内存索引节点表中。与磁盘索引节点相比,内存索引节点增加了如下字段:

·索引节点号:标志内存索引节点对应的磁盘索引节点号。因为索引节点按顺序方式存储在磁盘上,所以系统用索引节点的顺序标志磁盘索引节点。

·使用状态:用以指示内存索引节点是否上锁,是否有进程正在等待此索引节点解锁,索引节点是否被修改等。

·访问计数:记录当前有多个进程正在访问此索引节点。

·设备号:文件所属文件系统的设备号。

·内存索引节点指针:内存索引节点也有两种类型的链表,空闲链表和散列队列。因此内存索引节点应有相应的指针。

(2)索引节点的分配与回收

UNIX系统中分配索引节点由ialloc过程完成。当新建文件时,首先检查超级块是否上锁,若已上锁,则进程睡眠等待;若没有上锁,为新建文件分配一个空闲磁盘索引节点,并进行初始化,填写有关文件属性,分配一个内存索引节点。因为在UNIX系统中,每创建一新文件,随之便将它打开。所以,在分配了磁盘索引节点后,便调用iget过程,再为之分配内存索引节点,并对它进行初始化,然后把磁盘索引节点的内容复制到内存索引节点中;最后将空闲磁盘索引节点计数减1,并置超级块修改标志后返回。

文件被删除后,需要收回其占用的磁盘块和相应的磁盘索引节点。文件被关闭后,需要回收内存索引节点。UNIX系统中,回收磁盘索引节点由ifree过程完成,回收内存索引节点由iput过程完成。

7.目录管理

UNIX的目录结构是多级树形结构,允许用户任意深度地建立子目录,直至文件空间区用完为止。通常,每个文件在文件目录中有一个目录项,通过查找文件目录可找到该文件的目录项和对应的索引节点,进而找到文件存放的物理位置。

(1)构造目录

在创建一个新文件或共享某个已经存在的文件时,系统都要在其父目录文件中为之创建一个目录项。在UNIX系统中,构造目录的任务由makenode过程完成,该过程由系统调用creat调用。

makenode过程首先调用ialloc过程来为新建的文件分配一个磁盘索引节点和内存索引节点,若分配失败便返回;若分配成功,为内存索引节点赋初值,然后调用写目录过程wdir,将用户提供的文件名与分配给该文件的磁盘索引节点号一起构成一新目录项,再将它记入其父目录文件中。

(2)删除目录

当某一个用户进程不再需要某文件时,利用系统调用unlink请求删除进程与该文件之间的链接。此时,系统对该文件的链接计数执行减1操作,并删除该用户进程的一个指定文件目录。当所有链接到该文件的用户进程都不再需要该文件,并且文件的链接计数为0时,系统自动执行删除该文件的操作,相应的目录项也被删除。

(3)检索目录

在UNIX系统中,当用户第一次访问某文件时,需要使用文件的路径名,系统按路径名去检索文件目录,得到该文件的磁盘索引节点,并返回给用户一个文件描述符。以后,用户便可利用该文件描述符来访问文件,这时系统不必再去检索文件目录。

UNIX提供namei过程来检索目录。当查找某个执行文件时,该过程返回相应的内存索引节点指针;当需要链接操作时,该过程返回路径名所指出的父目录文件的内存索引节点指针;当创建文件时调用该过程,如果没有找到相应的文件则正常返回,以便新建文件。