文件系统学习 -- FAT和Ext

文件系统是用户和硬盘数据打交道的接口,用户通过文件系统可以对文件内容进行各种操作。本篇将讨论目前最常见的两种文件系统: FAT和Ext

FAT

FAT文件系统曾经被广泛运用与DOS系统和早期的Windows系统,即使到了现在,部分U盘等存储设备使用的依然是FAT的文件系统格式。这种文件系统是最经典的一种文件系统。

基本设计思想

FAT的基本思想是: 由于文件是由一个一个block构成类似链表格式而组成的。我们可以为创建一个表专门表示block的分配信息。

以下给出一个例子:

fat

在此例中,file是我们需要研究的文件,从他的文件信息我们知道这个文件的数据起始于Block3,紧接着我们通过查询FAT发现下一个block是6,以此类推得到4,2。而block 2的next是-1,也就代表着这是文件的最后一个block。

FAT的作用是告诉我们在硬盘系统中怎么样将block数据块合成为一个文件,但是并没有告诉我们文件到底是从哪一个block开始的。所以我们还需要一个文件目录表(File Directory table)。

假设在上述例子中我们的File位于/pi/File,我们的FDT看起来将会是这样的:

fdt

/对应的FDT始终在index为0的位置,以方便我们可以找得到。FAT中我们把文件和目录统统看做文件。我们在/的FDT内发现文件(目录)pi的起始位置是在block 1,然后我们就继续在对应位置找到/pi的FDT表,就可以发现File的start block是Block 3,于是就知道了怎么样去访问这个文件。

那么,这个FDT表到底存在什么位置呢?

FAT16分区格式的FDT表占用固定的32个扇区,扇区地址紧跟在第2个FAT表之后(FAT在磁盘中的分配顺序下文将交代).FAT32分区格式没有固定的FDT表,在第2个FAT表之后就是数据区DATA。目录名和文件名也作为数据对待,存放在数据区内。也就是说FAT16的FDT表是在一个固定位置的,而FAT32的目录信息可能并不叫FDT,但他也以相同的的格式存储。都使用一个32字节长的“目录登记项”来说明目录或文件的有关特性。FAT16分区的目录登记项存放在固定位置的FDT表里,而FAT32分区的目录登记项存放在数据区里。

FAT16分区的目录登记项存放在固定位置的FDT表里,而FAT32分区的目录登记项存放在数据区里。

实现方式

FAT系统由三个主要部分构成:保留区域、 FAT表和数据区域。保留区域是FAT系统的总体描述,也就是这个系统的”使用指南”,包括MBR,DBR这种引导相关的记录等。FAT区域则保存了文件系统的所有簇的使用状况,即处于空闲状态的可用、已被使用和已损坏这三种状态。数据区域则保存了文件的数据,如一个文本文件的数据是 “pipipi” ,这三个数据就保存在这个区域。

fat_system

关于保留扇区的具体内容详情可见维基百科

FAT的主要实现有三种:

  • FAT12
  • FAT16
  • FAT32

FAT后面的数字代表了FAT表的大小(比特位数)。具体实现课参考维基百科

分析

现在我们对FAT的设计及实现有了了解,我们接下来对其做一点分析:

优点

  • 新建文件简单
  • 扩充文件简单
  • 空间利用率较高(不会有外部碎片,有内部碎片,与簇大小有关系)

缺点

  • 有时访问效率比较低下,由于查找一个文件的内容必须从头开始遍历,就算只需要最后的内容

EXT

另外一种流行的文件系统是Ext(Extended Format)。EXT系统被广泛运用于Linux上,它有Ext2, Ext3, Ext4等版本,不过他们的基本思想比较类似。

基本设计思想

在EXT文件系统中,每一个文件都有一个对应的inode数据结构对其进行描述:(图片来自于《鸟哥的Linux私房菜》)

inode

Inode的大小是固定的,Inode的第一个部分是文件的Metadata,描述这个文件的各种性质。接着inode存储着15个地址:前12个地址中,每一个地址都直接指向一个数据块Data Block,这是为了对于小文件而言有更好的存储效率。第13个地址指向一个256个项的表,这个表的每一项都对应一个数据块,这瞬间就让inode可存储的数据大小大了许多。如果这还不够的话,第14个地址指向一个二重表,表的每一项都指向一个表,指向的表每一项都指向对应的数据块。第15个地址指向一个三重表,这样的话文件的大小就可以非常大了。以每一个block大小为1K为例,单个文件的总存储大小可以达到12+256+256*256+256*256*256(K) = 16GB

inode1(图片来自Udacity)

上述例子描述了目录相关的存储方法。假设我们要找的文件位于/foo/File.txt。首先我们找到根目录对应的inode,在他的数据区里找到foo对应的inode的地址,然后找到foo的inode数据区域在找到File.txt对应inode的地址,就可以访问到inode内部内容了。

实现方式

Ext文件系统由以下几个部分组成:superblock,文件系统描述,块对应表,inode对应表,inode table和Data Block。

inode_system

superblock

Superblock是记录整个文件系统相关信息的地方,没有superblock就没有这个文件系统。记录的信息包括:

  • block与inode的总量
  • 未使用和已使用的block/inode总量
  • block与inode的大小
  • 文件系统的挂载时间,最近一次写入数据的时间等
  • validbit数值,若被挂载则valid bit为0,否则为1
  • superblock可能会在其他的block group内备份
  • 可以用dumpe2fs查看

文件系统描述

这个区段可以描述每个block group的开始与结束的block号码,以及说明每个区段(superblock, bitmap, inodemap, data block)分别介于哪一个block号码之间。也可以使用dumpe2fs查看。

块对应表 - block bitmap

当我们在添加文件是需要用到新的block记录数据,那我们怎么知道哪一个block是空闲的呢?块对应表将记录这些。通过此表我们可以快速找到可使用的空间来处理文件。并且再删除文件中也记录下来,把对应的block好嘛设置为空闲。

inode对应表 - inode bitmap

与block bitmap类似,记录的是使用中和未使用的inode的情况。

inode table

inode的内容主要是记录文件的属性metadata以及该文件的实际数据放在哪一个block内。inode table的组成可见Ext的基本设计思想。

Data Block

data block是用来放置文件内容的地方,在Ext2文件系统中所支持的block大小有1KB,2KB及4KB三种。在格式化的时候block的大小就已经固定了,且每个block都有编号,以方便inode的记录。由于block大小的差别可能会导致文件系统支持的最大磁盘容量不一样。

分析

  • 新建文件简单
  • 扩充文件简单
  • 空间利用率较高(不会有外部碎片,有内部碎片,与簇大小有关系)
  • 即使在随机访问文件里的数据,效率也比较高

参考资料