Each blocks group is accompanied by a group descriptor. The group
descriptor summarizes some necessary information about the specific group
block. Follows the definition of the group descriptor, as defined in
/usr/include/linux/ext2_fs.h:
struct ext2_group_desc
{
__u32 bg_block_bitmap; /* Blocks bitmap block */
__u32 bg_inode_bitmap; /* Inodes bitmap block */
__u32 bg_inode_table; /* Inodes table block */
__u16 bg_free_blocks_count; /* Free blocks count */
__u16 bg_free_inodes_count; /* Free inodes count */
__u16 bg_used_dirs_count; /* Directories count */
__u16 bg_pad;
__u32 bg_reserved[3];
};
The last three variables: bg_free_blocks_count, bg_free_inodes_count and bg_used_dirs_count provide statistics about the use of the three
resources in a blocks group - The blocks, the inodes and the
directories. I believe that they are used by the kernel for balancing
the load between the various blocks groups.
bg_block_bitmap contains the block number of the block allocation
bitmap block. This is used to allocate / deallocate each block in the
specific blocks group.
bg_inode_bitmap is fully analogous to the previous variable - It
contains the block number of the inode allocation bitmap block, which
is used to allocate / deallocate each specific inode in the filesystem.
bg_inode_table contains the block number of the start of the
inode table of the current blocks group. The inode table is
just the actual inodes which are reserved for the current block.
The block bitmap block, inode bitmap block and the inode table are created when the filesystem is created.
The group descriptors are placed one after the other. Together they make the
group descriptors table.
Each blocks group contains the entire table of group descriptors in its second block, right after the superblock. However, only the first copy (in group 0) is actually used by the kernel. The other copies are there for backup purposes and can be of use if the main copy gets corrupted.