When partitioning, each partition is a file system, and the block at the beginning of each file system is called a super block. Super blocks are used to store file system size, empty and filled blocks, their respective totals, and other such information. That is to say, when we want to use this partition for data access, the first thing we need to go through is the super block. Therefore, if the super block is broken, this disk will be useless.
The Chinese name of super block is a super block. It is the first byte starting with a hard disk partition. The first byte starts with byte 0, and the second bytes starting from byte 1024. The data in the super block is actually the control information of the file volume. It can also be said that it is a volume resource table, and most information about the file volume is saved here. For example, the size of each block in a hard disk partition, the number of block groups on the hard disk partition, and the number of inodes in each block group.
The super block structure is:
/* The super block comes first in the block group */
Typedef struct tagext2_super_block
{
Uint32_t s_inodes_count;/* Total no of inodes */
Uint32_t s_blocks_count;/* Total no of blocks */
Uint32_t s_r_blocks_count;/* Total no of blocks reserved for exclusive use of superuser */
Uint32_t s_free_blocks_count;/* Total no of free blocks */
Uint32_t s_free_inodes_count;/* Total no of free inodes */
Uint32_t s_first_data_block;/* position of the first data block */
Uint32_t s_log_block_size;/* used to compute Logical Block Size in bytes */
Uint32_t s_log_frag_size;/* used to compute logical fragment size */
Uint32_t s_blocks_per_group;/* Total number of blocks contained in the group */
Uint32_t s_frags_per_group;/* Total number of fragments in A group */
Uint32_t s_inodes_per_group;/* Number of inodes in A group */
Uint32_t s_mtime;/* time at which the last Mount was saved med */
Uint32_t s_wtime;/* time at which the last write was completed MED */
Uint16_t s_mnt_count;/* Number of time the FS system has been mounted in R/W mode without having checked */
Uint16_t s_max_mnt_count;/* The Max no of times the FS can be mounted in R/W mode before A check must be done */
Uint16_t s_magic;/* a number that identifies the FS (eg. 0xef53 for ext2 )*/
Uint16_t s_state;/* gives the State of FS (eg. 0x001 is unmounted cleanly )*/
Uint16_t s_pad;/* unused */
Uint16_t s_minor_rev_level ;/**/
Uint32_t s_lastcheck;/* The time of last check completed MED */
Uint32_t s_checkinterval;/* The Max possible time between checks on the FS */
Uint32_t s_creator_ OS;/* OS */
Uint32_t s_rev_level;/* revision level */
Uint16_t s_def_resuid;/* default uid for reserved blocks */
Uint16_t s_def_regid;/* default gid for reserved blocks */
/* For ext2_dynamic_rev superblocks only */
Uint32_t s_first_ino;/* first non-reserved inode */
Uint16_t s_inode_size;/* size of inode structure */
Uint16_t s_block_group_nr;/* block group # Of This superblock */
Uint32_t s_feature_compat;/* compatible feature set */
Uint32_t s_feature_incompat;/* incompatible feature set */
Uint32_t s_feature_ro_compat;/* readonly-compatible feature set */
Uint8_t s_uuid [16];/* 128-bit UUID for volume */
Char s_volume_name [16];/* volume name */
Char s_last_mounted [64];/* directory where last mounted */
Uint32_t s_algorithm_usage_bitmap;/* For compression */
Uint8_t s_prealloc_blocks;/* NR of blocks to try to preallocate */
Uint8_t s_prealloc_dir_blocks;/* NR to preallocate for dirs */
Uint16_t s_padding1;
Uint32_t s_reserved [204];/* unused */
} Ext2_super_block;
In ext2read, the superblock reading function is Mount. This function:
Int ext2partition: Mount ()
{
Ext2_super_block sblock;
Int gsizes, gsizeb;/* size of total group DESC in sectors */
Char * tmpbuf;
// Read the super block data. The read location is 1024 bytes after the first byte of the partition.
Read_disk (handle, & sblock, relative_sect + 2, 2, sect_size);/* read superblock of root */
If (sblock. s_magic! = Ext2_super_magic)
{
Printf ("bad super block. The drive % s is not ext2 formatted. \ n", linux_name.c_str ());
Return-1;
}
// Determine whether the partition supports the ext2 feature
If (sblock. s_feature_incompat & ext2_feature_incompat_compression)
{
Printf ("file system compression is used which is not supported. \ n ");
}
// Obtain the block size.
Blocksize = ext2_block_size (& sblock );
// Obtain the number of inodes in each group.
Inodes_per_group = ext2_inodes_per_group (& sblock );
// Obtain the length of each inode struct.
Inode_size = ext2_inode_size (& sblock );
Printf ("block size % d, indium % d, inodesize % d \ n", blocksize, inodes_per_group, inode_size );
// Obtain the total number of groups, using the number of blocks in the entire partition/The number of blocks in each group
Totalgroups = (sblock. s_blocks_count)/ext2_blocks_per_group (& sblock );
// Obtain the description of all groups in the partition.
Gsizeb = (sizeof (ext2_group_desc) * totalgroups );
// Obtain the number of sectors occupied by all group descriptions.
Gsizes = (gsizeb/sect_size) + 1;
// Allocate the description space for all groups
Desc = (ext2_group_desc *) calloc (totalgroups, sizeof (ext2_group_desc ));
If (DESC = NULL)
{
Printf ("not enough memory: Mount: Desc: exiting \ n ");
Exit (1 );
}
// Allocate the storage space of the byte length occupied by all group descriptions
If (tmpbuf = (char *) malloc (gsizes * sect_size) = NULL)
{
Printf ("not enough memory: Mount: tmpbuf: exiting \ n ");
Exit (1 );
}
/* Read all group descriptors and store in buffer */
/* I really dont know the official start location of group descriptor array */
If (blocksize/sect_size) <= 2)
{
// Relative_sect indicates the start fan ID of the partition relative to the entire hard disk.
Read_disk (handle, tmpbuf, relative_sect + (blocksize/sect_size) + 2), gsizes, sect_size );
}
Else
{
// Relative_sect is the start sector number of the partition relative to the entire hard disk. Why is the size of a block offset? Offset a block because the first block stores information such as the boot block.
Read_disk (handle, tmpbuf, relative_sect + (blocksize/sect_size), gsizes, sect_size );
}
// Obtain all group information and store it in the cache DESC.
Memcpy (DESC, tmpbuf, gsizeb );
Free (tmpbuf );
Return 0;
}
Super block in ext2 file system and corresponding code