好文分享:EXT文件系统机制原理详解
下图是一个ext4文件系统的superblock的信息,ext家族的文件系统都能使用dumpe2fs -h获取。 ![]() 2.3 块组描述符表(GDT)既然文件系统划分了块组,那么每个块组的信息和属性元数据又保存在哪里呢? ext文件系统每一个块组信息使用32字节描述,这32个字节称为块组描述符,所有块组的块组描述符组成块组描述符表GDT(group descriptor table)。 虽然每个块组都需要块组描述符来记录块组的信息和属性元数据,但是不是每个块组中都存放了块组描述符。ext文件系统的存储方式是:将它们组成一个GDT,并将该GDT存放于某些块组中,存放GDT的块组和存放superblock和备份superblock的块相同,也就是说它们是同时出现在某一个块组中的。读取时也总是读取Group0中的块组描述符表信息。 假如block大小为4KB的文件系统划分了143个块组,每个块组描述符32字节,那么GDT就需要143*32=4576字节即两个block来存放。这两个GDT block中记录了所有块组的块组信息,且存放GDT的块组中的GDT都是完全相同的。 下图是一个块组描述符的信息(通过dumpe2fs获取)。 ![]() 2.4 保留GDT(Reserved GDT)保留GDT用于以后扩容文件系统使用,防止扩容后块组太多,使得块组描述符超出当前存储GDT的blocks。保留GDT和GDT总是同时出现,当然也就和superblock同时出现了。 例如前面143个块组使用了2个block来存放GDT,但是此时第二个block还空余很多空间,当扩容到一定程度时2个block已经无法再记录块组描述符了,这时就需要分配一个或多个Reserved GDT的block来存放超出的块组描述符。 由于新增加了GDT block,所以应该让每一个保存GDT的块组都同时增加这一个GDT block,所以将保留GDT和GDT存放在同一个块组中可以直接将保留GDT变换为GDT而无需使用低效的复制手段备份到每个存放GDT的块组。 同理,新增加了GDT需要修改每个块组中superblock中的文件系统属性,所以将superblock和Reserved GDT/GDT放在一起又能提升效率。 3.Data Block![]() 如上图,除了Data Blocks其他的部分都解释过了。data block是直接存储数据的block,但事实上并非如此简单。 数据所占用的block由文件对应inode记录中的block指针找到,不同的文件类型,数据block中存储的内容是不一样的。以下是Linux中不同类型文件的存储方式。
常规文件的存储就不解释了,下面分别解释特殊文件的存储方式。 3.1 目录文件的data block 对于目录文件,其inode记录中存储的是目录的inode号、目录的属性元数据和目录文件的block指针,这里面没有存储目录自身文件名的信息。 而其data block的存储方式则如下图所示。 ![]() 由图可知,在目录文件的数据块中存储了其下的文件名、目录名、目录本身的相对名称"."和上级目录的相对名称"..",还存储了指向inode table中这些文件名对应的inode号的指针(并非直接存储inode号码)、目录项长度rec_len、文件名长度name_len和文件类型file_type。注意到除了文件本身的inode记录了文件类型,其所在的目录的数据块也记录了文件类型。由于rec_len只能是4的倍数,所以需要使用" |