原著: David A Rusling
翻译: Banyan & fifa
第九章 文件系统
本章主要描叙Linux核心对文件系统的支持, 虚拟文件系统(VFS)以及Linux核心对实际文件系统的支持。
Linux的最重要特征之一就是支持多种文件系统。这样它更加灵活并可以和许多其它种操作系统共存。在本文写作时Linux已经支持15种文件系统:ext,ext2,xia,minix,umsdos,msdos,vfat,proc,smb,ncp,iso9660,sysv,hpfs,affs以及ufs。毫无疑问,今后支持的文件系统类型还将增加。
Linux和Unix并不使用设备标志符(如设备号或驱动器名称)来访问独立文件系统,而是通过一个将整个文件系统表示成单一实体的层次树结构来访问它。Linux每安装(mount)一个文件系统时都会其加入到文件系统层次树中。不管是文件系统属于什么类型,都被连接到一个目录上且此文件系统上的文件将取代此目录中已存在的文件。这个目录被称为安装点或者安装目录。当卸载此文件系统时这个安装目录中原有的文件将再次出现。
当磁盘初始化时(使用fdisk),磁盘中将添加一个描叙物理磁盘逻辑构成的分区结构。每个分区可以拥有一个独立文件系统如EXT2。文件系统将文件组织成包含目录,软连接等存在于物理块设备中的逻辑层次结构。包含文件系统的设备叫块设备。Linux文件系统认为这些块设备是简单的线性块集合,它并不关心或理解底层的物理磁盘结构。这个工作由块设备驱动来完成,由它将对某个特定块的请求映射到正确的设备上去;此块所在硬盘的对应磁道、扇区及柱面数都被保存起来。不管哪个设备持有这个块,文件系统都必须使用相同的方式来寻找并操纵此块。Linux文件系统不管(至少对系统用户来说)系统中有哪些不同的控制器控制着哪些不同的物理介质且这些物理介质上有几个不同的文件系统。文件系统甚至还可以不在本地系统而在通过网络连接的远程硬盘上。设有一个根目录内容如下的SCSI硬盘:
A E boot etc lib opt tmp usr
C F cdrom fd proc root var sbin
D bin dev home mnt lost+found
此时不管是用户还是程序都无需知道他们现在操纵的这些文件中的/C实际上是位于系统第一个IDE硬盘上并已安装VFAT文件系统。在此例中/E表示系统中第二个IDE控制器上的主IDE硬盘。至于第一个IDE控制器是PCI控制器和第二个则是控制IDE CDROM的ISA控制器无关紧要。当使用modem通过PPP网络协议来拨入网络时,可以将Alpha AXP Linux文件系统安装到/mnt/remote目录下。
文件系统中的文件是数据的集合;包含本章内容的文件是一个名叫filesystems.tex的ASCII文件。文件系统不仅包含着文件中的数据而且还有文件系统的结构。所有Linux用户和程序看到的文件、目录、软连接及文件保护信息等都存储在其中。此外文件系统中必须包含安全信息以便保持操作系统的基本完整性。没人愿意使用一个动不动就丢失数据和文件的操作系统。
Linux最早的文件系统是Minix,它受限甚大且性能低下。其文件名最长不能超过14个字符(虽然比8.3 文件名要好)且最大文件大小为64M字节。64M字节看上去很大,但实际上一个中等的数据库将超过这个尺寸。 第一个专门为Linux设计的文件系统被称为扩展文件系统(Extended File System)或EXT。它出现于1992年四月,虽然能够解决一些问题但性能依旧不好。1993年扩展文件系统第二版或EXT2被设计出来并添加到Linux中。它是本章将详细讨论的文件系统。
将EXT文件系统添加入Linux产生了重大影响。每个实际文件系统从操作系统和系统服务中分离出来,它们之间通过一个接口层:虚拟文件系统或VFS来通讯。
VFS使得Linux可以支持多个不同的文件系统,每个表示一个VFS的通用接口。由于软件将Linux文件系统的所有细节进行了转换, 所以Linux核心的其它部分及系统中运行的程序将看到统一的文件系统。 Linux的虚拟文件系统允许用户同时能透明地安装许多不同的文件系统。
虚拟文件系统的设计目标是为Linux用户提供快速且高效的文件访问服务。同时它必须保证文件及其数据的正确性。这两个目标相互间可能存在冲突。当安装一个文件系统并使用时, Linux VFS为其缓存相关信息。此缓存中数据在创建、写入和删除文件与目录时如果被修改,则必须谨慎地更新文件系统中对应内容。 如果能够在运行核心内看到文件系统的数据结构, 那么就可以看到那些正被文件系统读写的数据块。描叙文件与目录的数据结构被不断的创建与删除而设备驱动将不停地读取与写入数据。这些缓存中最重要的是Buffer Cache,它被集成到独立文件系统访问底层块设备的例程中。当进行块存取时数据块首先将被放入Buffer Cache里并根据其状态保存在各个队列中。此Buffer Cache不仅缓存数据而且帮助管理块设备驱动中的异步接口。
9.1 第二代扩展文件系统(EXT2)
图9.1 EXT2文件系统的物理分布
第二代扩展文件系统由Rey Card设计,其目标是为Linux提供一个强大的可扩展文件系统。它同时也是Linux界中设计最成功的文件系统。
象很多文件系统一样, EXT2建立在数据被保存在数据块中的文件内这个前提下。这些数据块长度相等且这个长度可以变化,某个EXT2文件系统的块大小在创建(使用mke2fs)时设置。 每个文件的大小和刚好大于它的块大小正数倍相等。如果块大小为1024字节而一个1025字节长的文件将占据两个1024字节大小的块。这样你不得不浪费差不多一般的空间。我们通常需要在CPU的内存利用率和磁盘空间使用上进行折中。而大多数操作系统,包括Linux在内,为了减少CPU的工作负载而被迫选择相对较低的磁盘空间利用率。并不是文件中每个块都包含数据,其中有些块被用来包含描叙此文件系统结构的信息。EXT2通过一个inode结构来描叙文件系统中文件并确定此文件系统的拓扑结构。 inode结构描叙文件中数据占据哪个块以及文件的存取权限、文件修改时间及文件类型。EXT2文件系统中的每个文件用一个inode来表示且每个inode有唯一的编号。文件系统中所有的inode都被保存在inode表中。 EXT2目录仅是一个包含指向其目录入口指针的特殊文件(也用inode表示)。
图9.1给出了占用一系列数据块的EXT2文件系统的布局。对文件系统而言文件仅是一系列可读写的数据块。文件系统并不需要了解数据块应该放置到物理介质上什么位置,这些都是设备驱动的任务。无论何时只要文件系统需要从包含它的块设备中读取信息或数据,它将请求底层的设备驱动读取一个基本块大小整数倍的数据块。EXT2文件系统将它所使用的逻辑分区划分成数据块组。每个数据块组将那些对文件系统完整性最重要的信息复制出来, 同时将实际文件和目录看作信息与数据块。为了发生灾难性事件时文件系统的修复,这些复制非常有必要。以下一节将着重描叙每个数据块组的内容。
9.1.1 The EXT2 Inode
图9.2 EXT2 Inode
在EXT2文件系统中inode是基本块;文件系统中的每个文件与目录由唯一的inode来描叙。每个数据块组的EXT2 inode被保存在inode表中, 同时还有一个位图被系统用来跟踪已分配和未分配的inode。图 9.2给出了EXT2 inode的格式,它包含以下几个域:
mode
它包含两类信息;inode描叙的内容以及用户使用权限。EXT2中的inode可以表示一个文件、目录、符号连接、块设备、字符设备或FIFO。
Owner Information
表示此文件或目录所有者的用户和组标志符。文件系统根据它可以进行正确的存取。
Size
以字节计算的文件尺寸。
Timestamps
inode创建及最后一次被修改的时间。
Datablocks
指向此inode描叙的包含数据的块指针。前12个指针指向包含由inode描叙的物理块, 最后三个指针包含多级间接指针。例如两级间接指针指向一块指针,而这些指针又指向一些数据块。这意味着访问文件尺寸小于或等于12个数据块的文件将比访问大文件快得多。
EXT2 inode还可以描叙特殊设备文件。虽然它们不是真正的文件, 但可以通过它们访问设备。所有那些位于/dev中的设备文件可用来存取Linux设备。例如mount程序可把设备文件作为参数。
9.1.2 EXT2 超块
超块中包含了描叙文件系统基本尺寸和形态的信息。文件系统管理器利用它们来使用和维护文件系统。 通常安装文件系统时只读取数据块组0中的超块,但是为了防止文件系统被破坏, 每个数据块组都包含了复制拷贝。超块包含如下信息:
Magic Number
文件系统安装软件用来检验是否是一个真正的EXT2文件系统超块。当前EXT2版本中为0xEF53。
Revision Level
这个主从修订版本号让安装代码能判断此文件系统是否支持只存在于某个特定版本文件系统中的属性。同时它还是特性兼容标志以帮助安装代码判断此文件系统的新特性是否可以安全使用。
Mount Count and Maximum Mount Count
系统使用它们来决定是否应对此文件系统进行全面检查。每次文件系统安装时此安装记数将递增,当它等于最大安装记数时系统将显示一条警告信息“maxumal mount count reached, running e2fsck is recommended”。
Block Group Number
超块的拷贝。
Block Size
以字节记数的文件系统块大小,如1024字节。
Blocks per Group
每个组中块数目。当文件系统创建时此块大小被固