Linux 磁盘分区和文件系统

本文以Ext2文件系统为例讲述Linux文件系统,由于Ext3文件系统是直接从Ext2文件系统发展而来,它完全兼容Ext2文件系统,所以本文的内容对于Ext2和Ext3都是适用的。

 

我们首先看一下磁盘分区和文件系统的结构图:

 

 

图 1 磁盘分区和文件系统结构图

 

整个磁盘可以分为1个MBR(Master Boot Record)和4个partitions。其中MBR的结构示意图如图2所示

 

图 2 MBR示意图

 

MBR不是本文的主要内容,所以不再详述,有兴趣的开发人员可以参考网址:https://www.ibm.com/developerworks/linux/library/l-linuxboot/

 

一个partition由两部分组成:Boot Sector和File System。Boot Sector大小是1KB,这是有PC标准规定的,用来存储磁盘分区信息和启动信息,任何File System都不能使用Boot Sector。

 

下面进入正题,详细介绍File System——文件系统。文件系统中存储的最小单位是块(Block),一个块究竟多大是在格式化时确定的,例如mke2fs的-b选项可以设定块大小为1024、2048或4096字节。Ext2文件系统将整个分区划成若干个同样大小的块组(Block Group),如图1所示,每个块组都由以下部分组成:

1.         Super Block(超级块)

描述整个分区的文件系统信息,例如块大小、文件系统版本号、上次mount的时间等等。超级块在每个块组的开头都有一份拷贝。

在Linux源代码中,Super Block对应的结构体如图3:

 

 

图 3 ext3_super_block结构体

 

超级块包含以下重要信息:

1)         Magic Number

对于Ext2和Ext3文件系统来说,这个字段的值应该正好等于0xEF53。如果不等的话,那么这个硬盘分区上肯定不是一个正常的Ext2或Ext3文件系统。从这里,我们也可以估计到,Ext2和Ext3的兼容性一定是很强的,不然的话,Linux内核的开发者应该会为Ext3文件系统另选一个Magic Number才对。

2)         Mount Count and Maximum Mount Count

每次mount此文件系统,Mount Count都会加1,当它等于Maximum Mount Count时系统将发出警告:maxumal mount count reached, running e2fsck is recommended。

3)         Block Group Number

Block Group的个数。

4)         Block Size

该文件系统在创建(格式化)时指定的block大小,如1024 Bytes。

5)         Blocks per Group

每个Block Group中block的个数,文件系统在创建时指定。

6)         Free Blocks

文件系统中空闲块数。

7)         Free Inodes

文件系统中空闲Inode数。

8)         First Inode

文件系统中第一个inode号。EXT2根文件系统中第一个inode将是指向'/'目录的目录入口。

2.         GDT(Group Descriptor Table,块组描述符表)

由很多块组描述符组成,整个分区分成多少个块组就对应有多少个块组描述符。每个块组描述符(Group Descriptor)存储一个块组的描述信息,例如在这个块组中从哪里开始是inode表,从哪里开始是数据块,空闲的inode和数据块还有多少个等等。和超级块类似,块组描 述符表在每个块组的开头也都有一份拷贝,这些信息是非常重要的,一旦超级块意外损坏就会丢失整个分区的数据,一旦块组描述符意外损坏就会丢失整个块组的数据,因此它们都有多份拷贝。通常内核只用到第0个块组中的拷贝,当执行e2fsck检查文件系统一致性时,第0个块组中的超级块和块组描述符表就会拷贝到其它块组,这样当第0个块组的开头意外损坏时就可以用其它拷贝来恢复,从而减少损失。

在Linux源代码中,GDT对应的结构体如图4:

 

图 4 ext3_group_desc结构体

 

GDT包含以下重要信息:

1)         Blocks Bitmap

对应此数据块组的块分配位图的块号。在块分配和回收时使用。

2)         Inode Bitmap

对应此数据块组的inode分配位图的块号。在inode分配和回收时使用。

3)         Inode Table

对应数据块组的inode表的起始块号。每个inode用下面5中介绍的ext3_inode结构来表示。

4)         Free blocks count, Free Inodes count, Used directory count

分别代表空闲的block数、空闲的inode数和使用的directory数。

3.         Block Bitmap(块位图)

一个块组中的块是这样利用的:数据块存储所有文件的数据,比如某个分区的块大小是1024字节,某个文件是2049字节,那么就需要三个数据块来存,即使第三个块只存了一个字节也需要占用一个整块;超级块、块组描述符表、块位图、inode位图、inode表这几部分存储该块组的描述信息。那么如何知道哪些块已经用来存储文件数据或其它描述信息,哪些块仍然空闲可用呢?块位图就是用来描述整个块组中哪些块已用哪些块空闲的,它本身占一个块,其中的每个bit 代表本块组中的一个块,这个bit为1表示该块已用,这个bit为0表示该块空闲可用。

为什么用df命令统计整个磁盘的已用空间非常快呢?因为只需要查看每个块组的块位图即可,而不需要搜遍整个分区。相反,用du命令查看一个较大目录的已用空间就非常慢,因为不可避免地要搜遍整个目录的所有文件。

与此相联系的另一个问题是:在格式化一个分区时究竟会划出多少个块组呢?主要的限制在于块位图本身必须只占一个块。用mke2fs格式化时默认块大小是1024字节,可以用-b参数指定块大小,现在设块大小指定为b字节,那么一个块可以有8b个bit,这样大小的一个块位图就可以表示8b个块的占用情况,因此一个块组最多可以有8b个块,如果整个分区有s个块,那么就可以有s/(8b)个块组。格式化时可以用-g参数指定一个块组有多少个块,但是通常不需要手动指定,mke2fs工具会计算出最优的数值。

4.         inode Bitmap(inode位图)

和块位图类似,本身占一个块,其中每个bit表示一个inode是否空闲可用。

5.         inode Table(inode表)

我们知道,一个文件除了数据需要存储之外,一些描述信息也需要存储,例如文件类型(常规、目录、符号链接等),权限,文件大小,创建/修改/访问时间等,也就是ls -l命令看到的那些信息,这些信息存在inode中而不是数据块中。每个文件都有一个inode,一个块组中的所有inode组成了inode表。

inode表占多少个块在格式化时就要决定并写入块组描述符中,mke2fs格式化工具的默认策略是一个块组有多少个8KB就分配多少个inode。由于数据块占了整个块组的绝大部分,也可以近似认为数据块有多少个8KB就分配多少 个inode,换句话说,如果平均每个文件的大小是8KB,当分区存满的时候inode表会得到比较充分的利用,数据块也不浪费。如果这个分区存的都是很 大的文件(比如电影),则数据块用完的时候inode会有一些浪费,如果这个分区存的都是很小的文件(比如源代码),则有可能数据块还没用完inode就 已经用完了,数据块可能有很大的浪费。如果用户在格式化时能够对这个分区以后要存储的文件大小做一个预测,也可以用mke2fs的-i参数手动指定每多少个字节分配一个inode。

EXT2 inode还可以描叙特殊设备文件。虽然它们不是真正的文件, 但可以通过它们访问设备。所有那些位于/dev中的设备文件可用来存取Linux设备。例如mount程序可把设备文件作为参数。

在Linux源代码中,GDT对应的结构体如图5:

 

图 5 ext3_inode结构体

 

inode包含以下重要信息:

1)         Mode

它包含两类信息;inode描叙的内容以及用户使用权限。EXT2中的inode可以表示一个文件、目录、符号连接、块设备、字符设备或FIFO。

2)         Owner Information

表示此文件或目录所有者的用户和组标志符。文件系统根据它可以进行正确的存取。

3)         Size

以字节计算的文件尺寸。

4)         Timestamps

inode创建及最后一次被修改的时间。

5)         Datablocks Pointers

指向此inode描叙的包含数据的块指针。前12个指针指向包含由inode描叙的物理块, 最后三个指针包含多级间接指针。例如两级间接指针指向一块指针,而这些指针又指向一些数据块。这意味着访问文件尺寸小于或等于12个数据块的文件将比访问大文件快得多。这种寻址方式如图6所示,详细解释如下:我们看到在inode里面可以存放 EXT3_N_BLOCKS(= 15)这么多个 block 指针。用户数据就从这些 block 里面获得。15个blocks不一定放得下全部的用户数据,在这里 ext3 文件系统采取了一种分层的结构。这组15个block指针的前12个是所谓的direct blocks,里面直接存放的就是用户数据。第13个block,也就是所谓的indirect block,里面存放的全部是block指针,这些block指针指向的block才被用来存放用户数据。第 14个block 是所谓的double indirect block,里面存放的全是block指针,这些block指针指向的block也被全部用来存放 block 指针,而这些 block 指针指向的 block,才被用来存放用户数据。第 15个block是所谓的triple indirect block,比上面说的double indirect block有多了一层 block指针。

 

图 6 数据块寻址方式

 

6.         Data Block(数据块)

根据不同的文件类型有以下几种情况

1)         对于常规文件,文件的数据存储在数据块中。

2)         对于目录,该目录下的所有文件名和目录名存储在数据块中,注意文件名保存在它所在目录的数据块中,除文件名之外,ls -l命令看到的其它信息都保存在该文件的inode中。注意这个概念:目录也是一种文件,是一种特殊类型的文件。

3)         对于符号链接,如果目标路径名较短则直接保存在inode中以便更快地查找,如果目标路径名较长则分配一个数据块来保存。

4)         设备文件、FIFO和socket等特殊文件没有数据块,设备文件的主设备号和次设备号保存在inode中。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值