Ext4 文件系统简析

  • 2018-08-03
  • 111
  • 0

目前,Linux普遍使用的文件系统是EXT3/4。EXT4文件系统是2.6.28内核以后支持的新的文件系统。EXT4原本的开发目的是作为EXT3的扩展开发包。但是EXT3的维护者们认为可能会影响到EXT3的稳定性,所以提议将EXT4作为一个新的文件系统用来开发,于是就有了EXT4这个新的文件系统。

EXT3/4文件系统的优势

EXTX文件系统作为目前流行的Linux OS中的默认文件系统,它有很多其他文件系统无法比拟的优势。
EXT3/4是日志式文件系统。在写入数据时,会记录每个细节,当数据意外丢失的时候,可以很快速的整理磁盘,从而恢复。同时 EXT4文件系统突破了子目录32000的限制,单个文件达到2TB,更适合于大型企业使用。

文件系统的基本组成

在Linux/Unix世界里,有一句很著名的话“anywhere any file”,可见文件对于linux来说非常重要。对于EXT3/4文件系统,它们的结构大致一样。

要想了解EXT文件系统,我们先来了解几个基本的概念。

  1. EXTX索引式文件系统,文件信息和数据块使用索引的方式来链接。
  2. Block:磁盘实际存储数据的地方,它是逻辑上向硬盘写入数据的最小单位,每一个block都有编号。在linux中,在格式化磁盘的时候可以选择它的大小。它的值对于系统的性能会有很大的影响。例如:如果将block设为1K(一般来说block设为1、2、4K),且你的服务器为大文件服务器,如电影服务器,那么在存储文件的时候,由于占用很多的block,就会使索引文件变得很大,使得文件系统性能降低。

  3. blockgroup:将许多block组合在一块就构成了blockgroup。为了方便管理,linux将众多block组成了若干blockgroup。每一个 blockgroup中都有相同数量的block,但是文件系统可能不是blockgroup的整数倍,所以可能最后一个blockgroup中的block会小于其他的。一般来说,linux在创建blockgroup的时候,会将每组的块数和每块的bit数定义为相等的数。

  4. superblock: 它包含了很多信息:block大小,inode大小(一会我们说),已使用和未使用的block,inode的数量。还有一些非实际性的数据:卷名,最后写入的时间,最后挂载的时间,挂载路径,最后一次fsck的时间,等等。可以说superblock记录了文件系统的所有信息,非常关键。

  5. inode:前面提到过EXT3/4是一种索引式的文件系统。Inode就是用来索引block用的。同时,在inode中存放了文件的权限,UID,GID,存放数据的block的位置,等等一些信息。注意:很多人误以为inode存放了文件名,但实际上文件名并不存放在inode中。

注意:要把扇区(sector)和块(block)区分开。sector是磁盘物理的分块,在以前一般512Byte一个扇区,随着存储容量的越来越大,2009年开始有大扇区磁盘,4KB一个扇区,如果操作系统格式化时实现了4KB对齐,那么存储效率会提高很多。block是逻辑上的分块,格式化时可以改变它的大小。操作系统存储数据的最小单位。

文件系统的结构

如图所示,在EXT3/4中文件系统中blockgroup的组成就是这样。前面说过superblock存储了整个filesystem的inode和block信息。

其实并不是每一个blockgroup中都有superblock。当filesystem启动了稀疏机制的时候,只有一部分的blockgroup中有superblock。此时的superblock主要是用来作为第一个blockgroup中superblock的备份。用做紧急恢复。

  1. 组描述符表:记录了文件系统中所有blockgroup的信息描述。一般来说每一个blockgroup中都有一个组描述符表的备份,但是和superblock一样,当激活了稀疏特征时,只有部分blockgroup中包含组描述符表。
  2. Block位图:由于blockgroup中block数和block中的bit数相等,所以块位图大小也就正好等于一个block。注意:block位图只表示本组内的block状态。块位图每个字节对应一个块,即每个字节对应8个块。如果某个块已被分配使用,则对应的快位图的bit被置为“1”,未使用的块则为“0”。一个字节的最低位所对应的块接在前一个字节最高位所对应的块之后。也就是说读字节时是从左到右,而读bit时是从右到左。
  3. Inode位图:一般来说文件系统给inode位图也分配了一个block的大小,但实际上是用不完的,因为inode肯定小于block的大小。Inode位图的工作方式和block位图的工作方式是一样的,这里就不多说了。
  4. Inode table:在EXT3/4中使用inode存放元数据,使用inode table存放本组的inode。基本inode只有128Byte,还有一种大inode有255Byte,但是它们的前128Byte是相同的。每组都有自己的inode table,且每个inode都有一个地址。前1-10个inode作为保留使用,只有2号inode具有实际意义:分配给根目录。用户的第一个文件可使用的inode编号为11。一般来说编号11分配给“lost+found”目录。当文件系统检查到有一个inode已被分配使用,却没有文件名指向它的时候,就将他添加到“lost+found”目录中,并为它分配一个新的文件名。
  5. inode:用于存放文件的权限,更改时间,用户及组,文件类别,以及所有block。权限,时间这些均使用几个字节去存放,这里不详细说。我们主要说一下索引block的几个字节。每一个block的指针都占4个字节。在inode中有12个Direct block的指针,1个Indirect block的指针,1个Level 2 Indirect block的指针,一个Level 3 Indirect block的指针。
  6. 在EXT3/4删除文件时,只清楚它的inode信息,除了“删除时间”。

注意:所有的inode编号不以组来编号,而是对于整个文件系统的绝对编号。即从第一个块的第一个inode为1依次后推。计算inode所属组:当前inode编号 –1 对每组inode取整 = 组号

EXT3/4和UFS一样,用于小文件的高速访问。因此每个inode存储着文件的前12个分配地址块,成为Direct block,这些块直接存放数据。当文件的大小超过了12个block,则用一个block来存放剩余的地址,指向这个block的指针称为Indirect block指针。如果12个Direct block和一个Indirect block仍然无法满足一个文件的需要,就需要用到Level 2 Indirect block。Level 2 Indirect block指向一个由Indirect block 指针列表组成的block。此block中的每个指针又分别指向一个Direct block指针列表所组成的block。最后,如果这样还无法满足要求,则要用到Level 3 Indirect block ,这个block由Level 2 Indirect block的指针列表组成。

目录项

上面我们曾经说到过,文件名并没有存放在inode中,而是存放在目录项中,那么目录项到底是什么呢?这小节我们将开始介绍目录项。

在linux中目录项专门用来存放文件名和目录名。他们保存在为目录分配的块中,包含文件或目录的inode地址信息。EXT3/4的目录和正常的文件差不多,相差之处只是在inode中的类型标识不一样。

一个目录项的结构很简单,目前有两种,一种是基本的,一种是新版本的。

含义旧版本 字节数新版本字节数
Inode序号4 Byte4 Byte
本目录项的长度字节数2 Byte2 Byte
名字长度2 Byte1 Byte
名字的ASCII码不定长度不定长度

对比之下可以知道,老版本给“名字长度”留了2个字节,但是linux中名字最多255个字符,1个字节就可以表示,所以开发者将名字长度改为1个字节,然后增加了文件类型,占用 1个 Byte。

下一小节,我们将要介绍如何增加和删除目录项,但是在此之前你要了解一些目录项的特征:

  1. 目录的大小只对应为其分配的block数,而与目录的文件数量无关。
  2. 每个子目录的头两个目录一定是“.”和“..”,分别代表,该目录本身和其父目录。跟在后面的则是本目录中的目录或文件。
  3. 根目录总是位于2号inode。
  4. 目录项具有动态的长度,因为文件名可以使1-255个字节间的任意值。因此,目录项中有一个字段用以说明名字的长度,同时也用一个本目录项的记录长度指出了下一个目录项的起始位置。
  5. 目录项的长度总是4的整数倍。

目录的删除

有人会问,为什么不先讲目录项的创建,而是先讲删除呢?这是因为先将删除会对理解目录项的创建更有帮助,先讲哪个在逻辑上并不影响理解。

当目录中有文件或其子目录被删除时,将会对它的目录项进行相应的改变,以使操作系统不再显示这些文件名。

操作系统使被删除目录项的前一项的记录长度值直接指向后一项的起始位置,已达到不再显示文件名的效果。

目录项的添加

当新建一个目录项时,操作系统检查每个目录项,对它们各自的名字长度和记录长度相比较,每个目录项除了名字以外,还需要8Byte的空间,然后增加到最近的4的整数倍个字节。如果一个目录项的记录字节大于它实际需要的长度,而多出的长度又足以存放将要新建的目录项时,则将新建的目录项便存放在此处。

链接文件

EXT3/4文件系统提供的硬链接和软链接的功能可以使用户为一个文件或目录定义多个名字。

硬链接

硬链接只可以在与源文件在同一文件系统下创建,不可以跨文件系统。
创建硬链接时,操作系统为硬链接分配一个新的目录项,并指向源inode节点。inode中的链接数也相应的加1。表示有不同的名字。

硬链接建立了以后,用户无法判定哪一个是原名,哪一个是链接名。所有的链接没有被删除前,文件不会真的被删除。

软链接

软链接也是为文件或目录提供一个其他的名字的方法。软链接可以跨文件系统。

操作系统使用一种特殊的动态链接类型文件创建软链接。在链接文件中保存了目的文件或目录的绝对路径。

如果路径小于60Byte,则直接保存在inode中。

挂载点

EXT3/4文件系统在使用时需要挂载,而挂载的目的路径称为挂载点。当挂载点中以前仍有文件或目录时,当挂载了新的分区后,源文件(目录)将会被暂时屏蔽。当挂载后,挂载点中只显示分区中的信息。

日志系统

文件系统的日志负责记录文件系统的更新,以便在出现问题的时候迅速恢复。

日志所使用的inode号在superblock中给出,理论上它可以使用任何一个inode,但是一般来说,日志使用8号inode。

日志分为兼容性和非兼容性。兼容性是在本地存放日志,非兼容性是在其他设备上存放日志。此值在superblock中可以设置。

而日志级别分为3种,Write back, Order, Data。

write back实际上就是没有日志。order是元数据日志,这种情况下性能损失实际上是很小的,因为元数据本来也没多大,多写一遍并不会有很大的开销。但是带来的好处是显而易见的,那就是断电以后可以不用fsck。

data是数据日志,这个是把数据也记入日志,开销会比较大,但是断电损失的数据会很少,按照5秒同步一次来说,断电时你最多就损失5秒的数据而已。

日志式文件系统是一种能够有效降低突然掉电文件丢失危险的文件系统。但是要注意,日志并不能让你完全不丢数据。,他只是让你能够免去开机时的FSCK。

linux中块的分配

这一小节中的linux特指linux操作系统,与其他类unix无关。linux在将一个块分配给inode时,试图尽量分配其组内的,目的是为了让磁盘在读取文件时,缩短磁头的运动行程。

如果一个文件需要增大时,linux使用“下一可分配”的策略在这个文件后来寻找可用的空闲块。

当一个目录需要增加存储块时,兼容文件系统特性将为其再分配存储块,以避免使其片段化。

如果在同一组没有足够的可用空间,则需要在另外的组中分配。

EXT3/4会设法阻止用户任意的分配文件系统中的块,superblock中有一个值定义了至少要为特殊用户保留多少个可用的块,这个特殊用户通常是指root。当可用分配块下降到限定的最小值时,普通用户将无法再建立新的文件,但管理员可以继续登录以做清理。

一个文件至少使用一个block,即便它并没有完全使用一个block,那所剩下的空间也不能被其他文件锁使用。

linux中inode的分配

inode的分配与block不同,具体如下:
如果是为文件创建节点,linux将会在该文件的父目录所在的组中为其创建inode,这样可以确保一个目录的信息位于一个大致的区域内。若这个组中没有空闲的inode或者block,则到其他的组中寻找分配位置,算法如下:

  1. linux使用二次方的哈希算法选择一个随机的组,即以当前组号为基准,每次讲组号增加2的次幂个组(如:1,2,4,8……)知道找到一个符合条件的组,或者因没有符合条件而退出。
  2. 如果上述算法无法找到合适的组,则从当前组开始向后线性寻找,直到找到或因无合适组而退出。

如果是为目录分配节点,则会将它分配在一个未分配空间较多的组。这样做是为了尽可能的平衡地使用每个组。算法是:

  1. 首先利用superblock记录的空闲inode和block数计算出文件系统中平均每组的使用率。然后从0号组开始对每个组进行检索,在找到的第一个inode/block空闲值小于平均值的组中新建inode。
    1. 若上述算法无法找到合适的组,则使用一个目录最少,inode最多的组来存放新的inode。 注:目录和空闲inode数都存放在组描述符表中。

文件名空间分配

当目录没有足够的空间存放新建文件名时,会先将文件名挂起,然后为目录分配块。
linux不允许一个目录项挂块边界。
未使用的目录项不会因为为了压缩目录的大小而被重新整理。


作者和出处(reposkeeper) 授权分享 By CC BY-SA 4.0 Creative Commons License

关注微信公众号,获取新文章的推送!
qrcode

评论

还没有任何评论,你来说两句吧

发表评论

*

code