Ext4文件系统的块组

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

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

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

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

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

文件系统磁盘布局

对应的,我们通过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特性的文件系统,会将若干个块组绑定为一个块组组,且块组的管理位图统一放在该组的第一个块组中,因此需要一个数据结构描述这些管理数据(位图等内容)的位置。这个数据结构叫块组描述符,其定义如下所示。

 276 struct ext4_group_desc
 277 {
 278         __le32  bg_block_bitmap_lo;     /* 逻辑块位图的位置,以文件系统块为单位,低32位 */
 279         __le32  bg_inode_bitmap_lo;     /* inode位图的位置,以文件系统块为单位 */
 280         __le32  bg_inode_table_lo;      /* Inodes table block */
 281         __le16  bg_free_blocks_count_lo;/* Free blocks count */
 282         __le16  bg_free_inodes_count_lo;/* Free inodes count */
 283         __le16  bg_used_dirs_count_lo;  /* Directories count */
 284         __le16  bg_flags;               /* EXT4_BG_flags (INODE_UNINIT, etc) */
 285         __le32  bg_exclude_bitmap_lo;   /* Exclude bitmap for snapshots */
 286         __le16  bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bbitmap) LE */
 287         __le16  bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+ibitmap) LE */
 288         __le16  bg_itable_unused_lo;    /* Unused inodes count */
 289         __le16  bg_checksum;            /* crc16(sb_uuid+group+desc) */
 290         __le32  bg_block_bitmap_hi;     /* Blocks bitmap block MSB */
 291         __le32  bg_inode_bitmap_hi;     /* Inodes bitmap block MSB */
 292         __le32  bg_inode_table_hi;      /* Inodes table block MSB */
 293         __le16  bg_free_blocks_count_hi;/* Free blocks count MSB */
 294         __le16  bg_free_inodes_count_hi;/* Free inodes count MSB */
 295         __le16  bg_used_dirs_count_hi;  /* Directories count MSB */
 296         __le16  bg_itable_unused_hi;    /* Unused inodes count MSB */
 297         __le32  bg_exclude_bitmap_hi;   /* Exclude bitmap block MSB */
 298         __le16  bg_block_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+bbitmap) BE */
 299         __le16  bg_inode_bitmap_csum_hi;/* crc32c(s_uuid+grp_num+ibitmap) BE */
 300         __u32   bg_reserved;
 301 };

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

如果引用本站的原创文章,请注明原文链接:,本站保留追究责任的权利!