【 tulaoshi.com - 编程语言 】
本章描述Linux如何维护它支持的文件系统中的文件。描述了虚拟文件系统(Virtual File System VFS)并解释了Linux核心中真实的文件系统如何被支持
Linux的一个最重要的特点之一使它可以支持许多不同的文件系统。这让它非常灵活,可以和许多其他操作系统共存。在写作本章的时候,Linux可一直支持15种文件系统:ext、ext2、xia、minix、umsdos、msdos、vfat、proc、smb、ncp、iso9660、sysv、hpfs、affs和ufs,而且不容置疑,随着时间流逝,会加入更多的文件系统。
在Linux中,象Unix一样,系统可以使用的不同的文件系统不是通过设备标识符(例如驱动器编号或设备名称)访问,而是连接成一个单一的树型的结构,用一个统一的单个实体表示文件系统。Linux在文件系统安装的时候把它加到这个单一的文件系统树上。所有的文件系统,不管什么类型,都安装在一个目录,安装的文件系统的文件掩盖了这个目录原来存在的内容。这个目录叫做安装目录或安装点。当这个文件系统卸载的时候,安装目录自己的文件又可以显现出来。
当磁盘初始化的时候(比如用fdisk),利用一个分区结构把物理磁盘划分成一组逻辑分区。每一个分区可以放一个文件系统,例如一个EXT2文件系统。文件系统在物理设备的块上通过目录、软链接等把文件组织成逻辑的树型结构。可以包括文件系统的设备是块设备。系统中的第一个IDE磁盘驱动器的第一个分区,IDE磁盘分区/dev/hda1,是一个块设备。Linux文件系统把这些块设备看成简单的线性的块的组合,不知道也不去关心底层的物理磁盘的尺寸。把对设备的特定的块的读的请求映射到对于设备有意义的术语:这个块保存在硬盘上的磁道、扇区和柱面,这是每一个块设备驱动程序的任务。一个文件系统不管它保存在什么设备上,都应该用同样的方式工作,有同样的观感。另外,使用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文件系统。本例中(实际是我家中的Linux系统),/E是次IDE控制器上的master IDE磁盘。第一个IDE控制器是PCI控制器,而第二个是ISA控制器,也控制着IDE CDROM,这些也都无关紧要。我可以用一个modem和PPP网络协议拨号到我工作的网络,这时,我可以远程安装我的Alpha AXP Linux系统的文件系统到/mnt/remote。
文件系统中的文件包含了数据的集合:包含本章源的文件是一个ASCII文件,叫做filesystems.tex。一个文件系统不仅保存它包括的文件的数据,也保存文件系统的结构。它保存了Linux用户和进程看到的所有的信息,例如文件、目录、软链接、文件保护信息等等。另外,它必须安全地保存这些信息,操作系统的基本的一致性依靠于它的文件系统。没有人可以使用一个随机丢失数据和文件的操作系统(不知道是否有,虽然我曾经被拥有的律师比Linux开发者还多的操作系统伤害过)。
Minix是Linux的第一个文件系统,有相当的局限,性能比较差。它的文件名不能长于14个字符(这仍然比8.3文件名要好),最大的文集大小是64M字节。第一眼看去,64M字节似乎足够大,但是设置中等的数据库需要更大的文件大小。第一个专为Linux设计的文件系统,扩展文件系统或EXT(Extend File System),在1992年4月引入,解决了许多问题,但是仍然感到性能低。所以,1993年,增加了扩展文件系统第二版,或EXT2。这种文件系统在本章稍后具体描述。
当EXT文件系统增加到Linux的时候进行了一个重要的开发。真实的文件系统通过一个接口层从操作系统和系统服务中分离出来,这个接口叫做虚拟文件系统或VFS。VFS答应Linux支持许多(通常是不同的)文件系统,每一个都向VFS表现一个通用的软件接口。Linux文件系统的所有细节都通过软件进行转换,所以所有的文件系统对于Linux核心的其余部分和系统中运行的程序显得一样。Linux的虚拟文件系统层答应你同时透明地安装许多不同的文件系统。
Linux虚拟文件系统的实现使得对于它的文件的访问尽可能的快速和有效。它也必须保证文件和文件数据正确地存放。这两个要求相互可能不平等。Linux VFS在安装和使用每一个文件系统的时候都在内存中高速缓存信息。在文件和目录创建、写和删除的时候这些高速缓存的数据被改动,必须非常小心才能正确地更新文件系统。假如你能看到运行的核心中的文件系统的数据结构,你就能够看到文件系统读写数据块,描述正在访问的文件和目录的数据结构会被创建和破坏,同时设备驱动程序会不停地运转,获取和保存数据。这些高速缓存中最重要的是Buffer Cache,在文件系统访问它们底层的块设备的时候结合进来。当块被访问的时候它们被放到Buffer Cache,根据它们的状态放在不同的队列中。Buffer Cache不仅缓存数据缓冲区,它也帮助治理块设备驱动程序的异步接口。
9.1 The Second Extended File System (EXT2)
EXT2被发明(Remy Card)作为Linux一个可扩展和强大的文件系统。它至少在Linux社区中是最成功的文件系统,是所有当前的Linux发布版的基础。EXT2文件系统,象所有多数文件系统一样,建立在文件的数据存放在数据块中的前提下。这些数据块都是相同长度,虽然不同的EXT2文件系统的块长度可以不同,但是对于一个特定的EXT2文件系统,它的块长度在创建的时候就确定了(使用mke2fs)。每一个文件的长度都按照块取整。假如块大小是1024字节,一个1025字节的文件会占用两个1024字节的块。不幸的是这一意味着平均你每一个文件浪费半个块。通常计算中你会用磁盘利用来交换CPU对于内存的使用,这种情况下,Linux象大多数操作系统一样,为了较少CPU的负载,使用相对低效率的磁盘利用率来交换。不是文件系统中所有的块都包含数据,一些块必须用于放置描述文件系统结构的信息。EXT2用一个inode数据结构描述系统中的每一个文件,定义了系统的拓扑结构。一个inode描述了一个文件中的数据占用了哪些块以及文件的访问权限、文件的修改时间和文件的类型。EXT2文件系统中的每一个文件都用一个inode描述,而每一个inode都用一个独一无二的数字标识。文件系统的inode都放在一起,在inode表中。EXT2的目录是简单的非凡文件(它们也使用inode描述),包括它们目录条目的inode的指针。
图9.1显示了一个EXT2文件系统占用了一个块结构的设备上一系列的块。只要提到文件系统,块设备都可以看作一系列能够读写的块。文件系统不需要关心自身要放在物理介质的哪一个块上,这是设备驱动程序的工作。当一个文件系统需要从包括它的块设备上读取信息或数据的时候,它请求对它支撑的设备驱动程序读取整数数目的块。EXT2文件系统把它占用的逻辑分区划分成块组(Block Group)。每一个组除了当作信息和数据块来存放真实的文件和目录之外,还复制对于文件系统一致性至关重要的信息。这种复制的信息对于发生灾难,文件系统需要恢复的时候是必要的。下面对于每一个块组的内容进行了具体的描述。
9.1.1 The EXT2 Inode(EXT2 I节点)
在EXT2文件系统中,I节点是建设的基石:文件系统中的每一个文件和目录都用一个且只用一个inode描述。每一个块组的EXT2的inode都放在inode表中,还有一个位图,让系统跟踪分配和未分配的I节点。图9.2显示了一个EXT2 inode的格式,在其他信息中,它包括一些域:
参见include/linux/ext2_fs_i.h
mode 包括两组信息:这个inode描述了什么和用户对于它的权限。对于EXT2,一个inode可以描述一个文件、目录、符号链接、块设备、字符设备或FIFO。
Owner Information 这个文件或目录的数据的用户和组标识符。这答应文件系统正确地进行文件访问权限控制
Size 文件的大小(字节)
Timestamps 这个inode创建的时间和它上次被修改的时间。
Datablocks 指向这个inode描述的数据的块的指针。最初的12个是指向这个inode描述的数据的物理块,最后的3个指针包括更多级的间接的数据块。例如,两级的间接块指针指向一个指向数据块的块指针的块指针。的这意味着小于或等于12数据块大小的文件比更大的文件的访问更快。
你应该注重EXT2 inode可以描述非凡设备文件。这些不是真正的文件,程序可以用于访问设备。/dev下所有的设备文件都是为了答应程序访问Linux的设备。例如mount程序用它希望安装的设备文件作为参数。
9.1.2 The EXT2 Superblock(EXT2超级块)
超级块包括这个文件系统基本大小和外形的描述。它里面的信息答应文件系统治理程序用于维护文件系统。通常文件系统安装时只有块组0中的超级块被读取,但是每一个块组中都包含一个复制的拷贝,用于系统崩溃的时候。除了其他一些信息,它包括:
参见include/linux/ext2_fs_sb.h