Ext4文件系统深度剖析|块组(Block Group)

前文已述,Ext4文件系统将磁盘空间划分为若干组,以这一组为单位管理磁盘空间,这个组叫做块组(Block Group)。那么为什么要划分为块组呢?其主要原因是方便对磁盘的管理,由于磁盘被划分为若干组,因此上层访问数据时碰撞的概率就会大大减小,从而提升文件系统的整体性能。简单来说,块组就是一块磁盘区域,而同时其内部有元数据来管理这部分区域的磁盘。

概括来说,我们知道超级块是管理整个文件系统(或者理解为承载整个文件系统的磁盘)的,而块组则是管理本区域内文件系统(或者理解为磁盘),管理的粒度逐渐减小。后面我们还会了解到更细粒度的管理单元。

既然块组管理磁盘的,那就要涉及如何管理的问题,包含两部分的内容,一方面是是用户层要读文件系统的内容时能够找到期望的数据(比如打开文件或者读文件内容),另一方面是写数据的时候能够找到空闲的逻辑磁盘块(比如创建文件或者向文件追加内容)。

那具体管理磁盘的逻辑块呢?这个其实就是块组中的元数据来处理的。这里先插一句,本着先简单后复杂的原则,本文首先介绍不具备Flexible Block Groups特性的文件系统。这种情况下,一个块组只管理本块组内的磁盘,而复杂的情况我们稍后介绍。

如图所示是一个磁盘块组的布局图,块组0和块组2是两个比较典型的块组。其中块组0包含的信息比较丰富,也即包含超级块、块组描述符和数据块位图等等内容,而块组2包含的信息则相对简单,只包含数据块位图、inode位图、inode表和数据区域。

Ext4文件系统深度剖析|块组(Block Group)

图1 Ext4磁盘数据布局图

对应的,我们通过dumpe2fs命令从磁盘获取关于块组的摘要信息,本文摘取磁盘中前3个块组的描述信息,其中包含块组0和块组2,可以看到摘要信息与上图一致。另外块组1起始跟块组0基本一致,只是我们从下面描述中得知其中包含超级块的备份。我们知道超级块是整个文件系统的入口,因此如果超级块被损坏,将导致整个文件系统不可用。因此Ext4在设计的时候包含一个(实际包含很多)超级块备份,保证即使在磁盘最开始超级块被破坏的情况下,仍然可以通过备份的超级块进行恢复,从而最大限度的保证文件系统的安全。

Group 0: (Blocks 0-32767)
 Checksum 0xffa8, unused inodes 8181
 Primary superblock at 0, Group descriptors at 1-1
 Reserved GDT blocks at 2-640
 Block bitmap at 641 (+641), Inode bitmap at 642 (+642)
 Inode table at 643-1154 (+643)
 31607 free blocks, 8181 free inodes, 2 directories, 8181 unused inodes
 Free blocks: 1161-32767
 Free inodes: 12-8192
Group 1: (Blocks 32768-65535) [INODE_UNINIT, BLOCK_UNINIT]
 Checksum 0x8b42, unused inodes 8192
 Backup superblock at 32768, Group descriptors at 32769-32769
 Reserved GDT blocks at 32770-33408
 Block bitmap at 33409 (+641), Inode bitmap at 33410 (+642)
 Inode table at 33411-33922 (+643)
 31613 free blocks, 8192 free inodes, 0 directories, 8192 unused inodes
 Free blocks: 33923-65535
 Free inodes: 8193-16384
Group 2: (Blocks 65536-98303) [INODE_UNINIT, BLOCK_UNINIT]
 Checksum 0x6c3b, unused inodes 8192
 Block bitmap at 65536 (+0), Inode bitmap at 65537 (+1)
 Inode table at 65538-66049 (+2)
 32254 free blocks, 8192 free inodes, 0 directories, 8192 unused inodes
 Free blocks: 66050-98303
 Free inodes: 16385-24576

前文啰嗦了这么多,我们其实主要是想说明的是块组是用来管理磁盘的,而且块组大致分为两种类型:

1. 一种是包含超级块等信息的块组

2. 一种是只包含位图等信息的块组

我们先介绍第2种块组,这种块组包含数据块位图、inode位图、inode表和数据块4部分内容。各部分的作用如下:

数据块位图: 用于标识该块组中那些逻辑块已经被使用,那些没有被使用。该部分占用1个逻辑块的存储空间(默认情况为4K),其中每1位标识该块组中逻辑块是否被占用(如果该位为0则表示相应偏移的逻辑块没有被使用,反之为已使用)。因此,以默认文件系统块大小计算,一个块组可以有32768(4096*8)个逻辑块,可以与上面dumpe2fs的信息对比一下。

inode位图: 用于标识inode表中的inode那些被使用了,那些没有被使用。该部分也占用1个逻辑块,使用方式与数据块位图类似。

inode列表: inode表一列表的形式保存了文件的元数据信息,包括文件的inode id、大小、扩展属性和访问时间等内容。由于inode结构的大小根据格式化文件系统的属性而有差异,因此该表占用的磁盘空间不定,通常占用若干个逻辑块的大小。

数据块: 上面元数据之外的存储区域都成为数据块区域,这些区域作为文件扩展属性和文件内数据的存放容器。

了解了这些概念,其实块组对磁盘的管理就很容易理解。其中,数据块位图实现对磁盘的直接管理,它标识磁盘的那些数据块已经被使用,那些数据块没有被使用,而inode位图则是对inode表进行管理的,它标识了inode表中inode的使用情况。这样在文件系统需要是用新的资源时,就可以根据位图查找没有被使用进行使用。

上面简述了第二种块组的管理方式,但对于第一种块组由于其前面有整个文件系统的元数据,逻辑块位图等位置就不好确定。另外对于具备Flexible Block Groups特性的文件系统,会将若干个块组绑定为一个块组组,且块组的管理位图统一放在该组的第一个块组中,因此需要一个数据结构描述这些管理数据(位图等内容)的位置。这个数据结构叫块组描述符,其定义如下所示。

struct ext4_group_desc
{
     __le32 bg_block_bitmap_lo; /* 逻辑块位图的位置,以文件系统块为单位,低32位 */
     __le32 bg_inode_bitmap_lo; /* inode位图的位置,以文件系统块为单位 */
     __le32 bg_inode_table_lo; /* Inodes table block */
     __le16 bg_free_blocks_count_lo;/* Free blocks count */
     __le16 bg_free_inodes_count_lo;/* Free inodes count */
     __le16 bg_used_dirs_count_lo; /* Directories count */
     __le16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */
     __le32 bg_exclude_bitmap_lo; /* Exclude bitmap for snapshots */
     __le16 bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bbitmap) LE */
     __le16 bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+ibitmap) LE */
     __le16 bg_itable_unused_lo; /* Unused inodes count */
     __le16 bg_checksum; /* crc16(sb_uuid+group+desc) */
     __le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */
     __le32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */
     __le32 bg_inode_table_hi; /* Inodes table block MSB */
     __le16 bg_free_blocks_count_hi;/* Free blocks count MSB */
     __le16 bg_free_inodes_count_hi;/* Free inodes count MSB */
     __le16 bg_used_dirs_count_hi; /* Directories count MSB */
     __le16 bg_itable_unused_hi; /* Unused inodes count MSB */
     __le32 bg_exclude_bitmap_hi; /* Exclude bitmap block MSB */
     __le16 bg_block_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+bbitmap) BE */
     __le16 bg_inode_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+ibitmap) BE */
     __u32 bg_reserved;
};

由于块组描述符的位置是确定的,因此可以根据该数据结构找到位图的位置,并进而对磁盘进行管理。后续我们再介绍具备Flexible Block Groups特性的文件系统的块组管理。

猜你喜欢

转载自blog.csdn.net/shuningzhang/article/details/89394350
今日推荐