学科分类
目录
Linux编程

ext2/ext3文件系统

经过mke2fs命令操作之后,磁盘或磁盘分区中就被创建了文件系统。下面以ext2文件系统中分区格式为例,来讲解Linux系统中的文件系统。

1、 Ext2文件系统

磁盘的容量一般是比较大的,一般情况下,磁盘中的空间被划分为多个分区,分区中的空间会再被划分为更小的子空间,这些子空间称为块组。每个块组都由相同个块(Block)组成,块是文件系统中存储数据的基本单位,块的大小在创建文件系统时确定。当使用mke2fs进行格式化时,可以使用其选项-b设定数据块大小为1024字节、2048字节或4096字节。需要注意的是,磁盘分区中存储数据的单位是块,也就是说,即便一个文件的大小不足一个块,它也要占用一个块来存储。假设一个分区中块的大小为1024字节,有个大小为1025的文件要存储到该分区中,那么这个文件就要占用2个块空间。

如图1所示,为磁盘分区格式化为ext2文件系统后的结构布局。

图1 Ext2文件系统布局

图1中磁盘分区的第一个部分为启动块(Boot Block),启动块占用一个块空间,用来存储磁盘的分区信息和启动信息。图1中启动块之后是多个块组,每个块组中包含6部分,即:超级块(Super Block)、块组描述符(GDT)、块位图(Block Bitmap)、位图(Inode Bitmap)、位表(Inode Table)、数据块(Data Blocks)。下面分别对这六个部分进行讲解。

① 超级块

超级块(Super Block)描述整个分区所用文件系统的信息,包括块的大小、块组中块的数量、inode占用的字节数、文件系统的版本类型等,它是文件系统中非常重要的一部分,超级块是分区正常使用的前提,为避免因超级块损坏导致分区异常,一般会在其它块组中备份超级块。

② 组描述符表

组描述符表(Group Descriptors Table,GDT)中存储块组描述符信息。一个块组描述符存储一个块组的描述信息,包括块组中inode表的位置、数据块的位置、空闲的inode数以及空闲数据块数量等,整个分区中所有块组的描述信息构成一张块组描述符表。

块组描述符表与超级块同等重要,一旦超级块与组描述符表损坏或丢失,系统将无法正常获取整个分区中文件系统的信息与块组的描述信息,分区也就不能正常使用,因此在其它块组中也存在块组描述符的备份。

③ 块位图

类似于堆空间的使用,文件在磁盘上占据的块空间通常也不是连续的,因此系统需要知道块的使用情况。Linux系统中用块位图(Block Bitmap)来描述块组中块的使用情况,它本身占用一个块,其中的每个位表示块组中一个块的状态:若块空闲则记为0,否则记为1。块组中块的数量与分区中块组的数量在块大小确定时就能确定:因为一个块最多记录8b(b为块的大小,单位为字节)个块的信息,所以块组中最多有8b个块;若整个分区中块的数量为s,那么就可以有s/(8b)个块组。

④ inode位图

inode位图记录块组中inode的使用情况,与块位图相同,inode位图中的每一位对应一个inode的使用情况。

⑤ inode表

除文件中的数据外,文件的属性信息,如文件类型、文件大小、时间戳、权限、所属组等,也要被记录。文件的属性信息保存在inode结构体中,每个文件都有一个inode,一个块组中的所有inode组成一个inode表(inode Tbale)。

inode表占据空间的大小也是在分区格式化时确定的,mke2fs命令默认以8k为单位分配inode,也就是说,一个块组中数据块有多少个8kb,就分配多少个inode,这个数值是一个平均值,当分区存满的时候inode表也会被充分利用。当然inode对应的空间大小也可以指定,若对该分区中将要存储的文件有个预估:比如将来这个分区中存储的都是大文件(如电影等大视频文件),可以提升inode对应的空间大小,降低inode表中inode的数量;如果将来这个分区中存储的都是1k、2k的小文件,则需降低inode对应的空间大小,扩大inode表的容量。

inode的数量要尽量合理,因为无论是数据块不足,还是inode耗尽,分区中都无法再存储文件,如此多余的inode或数据块无法被使用,将导致存储空间的浪费。

⑥ 数据块

数据块(Data Block)是块组中专门用于存储文件数据的块,系统可通过文件的inode编号,找到文件的inode结构体,再从inode结构体中获取到数据块在磁盘上的位置,进而读取数据信息。

Ext2文件系统的这种结构,有以下几个优点:

● Linux的管理员可以在创建ext2文件系统时,根据预期的平均文件长度来选择最佳的块大小,能有效防止磁盘碎片的产生,或者减少磁盘传送次数,减少系统消耗;

● 管理员也可以根据给定分区的大小,预计该分区中存放的文件数,从而确定分区中inode 的数量,保证磁盘空间的利用率;

● ext2文件系统将磁盘块划分为组,每组包含存放在相邻磁道上的数据块和索引结点,因此能降低对存放于一个单独块组中的文件并行访问时磁盘的平均寻道时间;

●支持快速符号链接。当链接文件的路径名较短时,ext2文件系统会将该路径存放在索引结点中。

虽然ext2文件有以上优点,但随着Linux的应用范围逐渐扩大,其弱点也逐渐显露。ext2文件系统最大的弱点是不包含日志功能,这成为Linux系统在关键行业应用中的一个致命缺点,因此ext2文件系统逐渐被ext3文件系统取代。

2、 Ext3文件系统特点

Ext3是一个完全兼容ext2文件系统的日志文件系统(Journaling file system),它在ext2的基础上,添加了一个被称为日志的块,专门来记录写入或修订文件时的步骤,除此之外,它的构造与ext2文件系统相同。

日志文件系统会在文件系统在发生变化时,先将相关信息写入系统中的日志中,再将此种变化应用到主文件系统的文件系统,即便操作中途因异常终止,文件系统也可以按照日志文件中的记录将数据恢复。而非日志文件系统不包含日志功能,很难处理操作中断导致的异常。

日志文件系统可以按照不同的方式进行工作,ext3中可通过对/etc/fstab文件中的data属性进行设置来修改文件系统的工作模式。日志文件系统的工作模式分为三种,其设置与实现方式分别如下:

① data=journal

当data=journal时,ext3的日志文件中会记录所有改变文件系统的数据和元数据,此种记录日志的方式风险最小,但速度较慢,因为所有的数据都要写入文件系统两次、写入日志一次。

② data=ordered

当data=ordered时,日志中只记录改变文件系统的元数据,且溢出文件数据要补充到磁盘中,这是ext3文件系统中日志的默认工作方式。此种方式的性能与风险都为中等。

③ data=writeback

当data=writeback时,只记录改变文件系统的元数据。这种工作模式的速度最快,因为它只记录元数据的变化,而无需关注文件数据相关信息的更新。但这种方式不能保证数据按顺序写入。

因为在ext2的基础上添加了日志功能,ext3在文件处理的速度、和数据完整性的保证方面都有很大提升,另外,因为ext3开发的初衷即为兼容ext2,因此ext2文件系统可以方便地转换为ext3文件系统。

多学一招:数据块寻址

文件的属性信息与数据分开存放,是为了提高文件查找的效率,那么文件的数据是如何被访问的呢?Linux系统中通过文件inode中的索引项Block来查找文件数据。

inode结构体的Block[]中共有15个索引项,记为Block[0]~Block[14],每个索引项占4个字节。其中Block[0]~Block[11]是直接索引项,这些索引项中直接存放数据块的编号,比如Block[2]中保存了17,就表示第17个块是该文件的数据块。

如果一个块的大小为1kb,且后三个索引也是一级索引项,那么这15个索引最大只能表示大小为15kb的文件,这显然远远不能满足需求。

因此Block[12]被设计为间接索引。间接索引存储的块号对应的块中,存储的不再是文件的数据,而是直接索引项,若一个块大小为b字节,那么一个间接索引项可以b/4个索引项,假设Block[12]~Block[14]为间接索引项,那么这15个索引项最多能表示(b/4)3b+b12大小的文件,若b为1,则最大表示268k大小的文件。

与15k相比,268k虽然大了许多,但仍不够用,因此Block[13]被设置为二级间接寻址项,Block[14]被设置为三级间接寻址项,如此,当块大小为1kb时,这15个索引项共能表示16.06G大小的文件。inode中各索引项的寻址方式如图2所示。其中索引Block[13]、Block[14]指向的Block中存储的都是索引。

图2 数据块寻址

若此时有一文件的路径名为:/czbk/itheima/bxg.c,在终端使用cat命令查看该文件的内容,那么系统查找文件bxg.c的步骤如下:

(1)内核找到根目录,访问根目录数据块中的dentry;

(2)遍历根目录的dentry,通过文件名czbk,匹配inumber;

(3)根据获得的czbk的inumber,到inode表中查找czbk索引结点所在的位置,访问其inode;

(4)根据文件czbk的inode信息,获取czbk数据块存储位置,访问其中的dentry;

(5)遍历目录czbk的dentry,通过文件名itheima,匹配inumber;

(6)根据获得的itheima的inumber,返回到inode表中查找itheima索引结点所在的位置,访问其inode;

(7)根据文件itheima的inode信息,获取itheima数据块存储位置,访问其中的dentry;

(8)遍历目录itheima的dentry,通过文件名bxg.c,匹配inumber;

(9)根据文件bxg.c的inumber,返回到inode表中查找bxg.c索引结点所在的位置;

(10)根据bxg.c的inode信息,获取文件bxg.c数据块所在位置,进行数据访问。

以上步骤不考虑因路径名中目录或文件不存在导致查找失败的情况。通过以上步骤可知,文件的查找时间与其路径名有关,且随着路径名的增长而逐渐增加。

点击此处
隐藏目录