Loading content...
Every ext file system begins with a single, critical data structure: the superblock. This 1024-byte structure contains the complete genetic code of the file system—its block size, total capacity, current state, feature flags, and the parameters needed to interpret every other structure on disk.
Without a valid superblock, an ext partition is essentially an undifferentiated mass of bytes. The kernel cannot determine where block groups begin, how to interpret inodes, or even what version of ext it's dealing with. This makes the superblock simultaneously the most important and most vulnerable structure in the file system.
Recognizing this vulnerability, ext file systems maintain multiple superblock copies at predictable locations throughout the disk. This redundancy has saved countless systems from catastrophic data loss—when the primary superblock becomes corrupted, recovery tools can reconstruct the file system using a backup copy.
Understanding the superblock is essential for file system administration, forensic analysis, and debugging mount failures. Every mke2fs, tune2fs, e2fsck, and mount operation fundamentally interacts with superblock data.
By the end of this page, you will understand the complete superblock structure, including every critical field and its purpose. You'll learn where backup superblocks are stored, how to recover from superblock corruption, and how the superblock evolves through ext2, ext3, and ext4 to support new features.
The superblock occupies a fixed, well-known location at the start of the file system, making it easy for boot loaders and mount utilities to locate.
Primary Superblock Location:
Partition Start
│
├── Byte 0-1023: Boot block (reserved for boot loader)
├── Byte 1024-2047: Superblock (primary copy)
├── Byte 2048+: Group descriptor table, bitmaps, etc.
The superblock always starts at byte offset 1024 from the beginning of the partition, regardless of block size. This fixed location ensures that mount can read the superblock to determine the block size before interpreting rest of the file system.
Why Byte 1024?
The first 1024 bytes are reserved for the boot sector:
By placing the superblock at offset 1024, ext avoids overwriting boot code that might be needed for bootable partitions.
The Superblock's Role:
The superblock serves as the file system's master configuration:
| Category | Information Stored |
|---|---|
| Dimensions | Total blocks, inodes, block size, blocks per group |
| Allocation State | Free block count, free inode count |
| Consistency | Mount count, last fsck time, filesystem state |
| Identity | UUID, volume label, creation time |
| Features | Compatible, incompatible, and read-only-compatible feature flags |
| Tuning | Mount options, error behavior, checkpoint interval |
| Journaling (ext3/4) | Journal inode, journal device, journal UUID |
Mount Process:
When Linux mounts an ext file system:
The superblock's magic number (0xEF53 at offset 56) identifies the file system as ext2/ext3/ext4. If this value is corrupted, the kernel will refuse to mount and report "wrong fs type" or "bad superblock." This is the first thing fsck and recovery tools check.
The ext superblock is a carefully designed structure that has evolved across ext2, ext3, and ext4. Let's examine its complete layout:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
// ext4 superblock structure (kernel's struct ext4_super_block)struct ext4_super_block { // ========== Block 0: Core Parameters (Offset 0-255) ========== __le32 s_inodes_count; /* 0x00: Total inode count */ __le32 s_blocks_count_lo; /* 0x04: Total block count (low 32 bits) */ __le32 s_r_blocks_count_lo; /* 0x08: Reserved blocks (low 32 bits) */ __le32 s_free_blocks_count_lo; /* 0x0C: Free block count (low 32 bits) */ __le32 s_free_inodes_count; /* 0x10: Free inode count */ __le32 s_first_data_block; /* 0x14: First data block (0 or 1) */ __le32 s_log_block_size; /* 0x18: Block size = 1024 << value */ __le32 s_log_cluster_size; /* 0x1C: Cluster size (bigalloc) */ __le32 s_blocks_per_group; /* 0x20: Blocks per group */ __le32 s_clusters_per_group; /* 0x24: Clusters per group */ __le32 s_inodes_per_group; /* 0x28: Inodes per group */ __le32 s_mtime; /* 0x2C: Last mount time */ __le32 s_wtime; /* 0x30: Last write time */ __le16 s_mnt_count; /* 0x34: Mount count since fsck */ __le16 s_max_mnt_count; /* 0x36: Max mounts before fsck */ __le16 s_magic; /* 0x38: Magic number (0xEF53) */ __le16 s_state; /* 0x3A: FS state (clean/error) */ __le16 s_errors; /* 0x3C: Error behavior */ __le16 s_minor_rev_level; /* 0x3E: Minor revision level */ __le32 s_lastcheck; /* 0x40: Last fsck time */ __le32 s_checkinterval; /* 0x44: Max time between fscks */ __le32 s_creator_os; /* 0x48: Creator OS (Linux=0) */ __le32 s_rev_level; /* 0x4C: Revision level (0 or 1) */ __le16 s_def_resuid; /* 0x50: Default UID for reserved */ __le16 s_def_resgid; /* 0x52: Default GID for reserved */ // ========== Dynamic Revision Extensions (Offset >= 84) ========== __le32 s_first_ino; /* 0x54: First non-reserved inode */ __le16 s_inode_size; /* 0x58: Inode size in bytes */ __le16 s_block_group_nr; /* 0x5A: Block group of this SB */ __le32 s_feature_compat; /* 0x5C: Compatible feature flags */ __le32 s_feature_incompat; /* 0x60: Incompatible feature flags */ __le32 s_feature_ro_compat; /* 0x64: Read-only compat features */ __u8 s_uuid[16]; /* 0x68: 128-bit UUID */ char s_volume_name[16]; /* 0x78: Volume label */ char s_last_mounted[64]; /* 0x88: Last mount point */ __le32 s_algorithm_usage_bitmap;/* 0xC8: Compression algorithm */ // ========== Performance Hints ========== __u8 s_prealloc_blocks; /* 0xCC: File prealloc blocks */ __u8 s_prealloc_dir_blocks; /* 0xCD: Dir prealloc blocks */ __le16 s_reserved_gdt_blocks; /* 0xCE: Reserved GDT blocks */ // ========== Journaling (ext3/ext4) ========== __u8 s_journal_uuid[16]; /* 0xD0: Journal superblock UUID */ __le32 s_journal_inum; /* 0xE0: Journal inode number */ __le32 s_journal_dev; /* 0xE4: Journal device number */ __le32 s_last_orphan; /* 0xE8: Head of orphan inode list */ __le32 s_hash_seed[4]; /* 0xEC: HTree hash seed */ __u8 s_def_hash_version; /* 0xFC: Default hash version */ __u8 s_jnl_backup_type; /* 0xFD: Journal backup type */ __le16 s_desc_size; /* 0xFE: Group descriptor size */ __le32 s_default_mount_opts; /* 0x100: Default mount options */ __le32 s_first_meta_bg; /* 0x104: First meta block group */ __le32 s_mkfs_time; /* 0x108: Filesystem creation time */ __le32 s_jnl_blocks[17]; /* 0x10C: Backup journal blocks */ // ========== 64-bit Support ========== __le32 s_blocks_count_hi; /* 0x150: Total blocks (high 32) */ __le32 s_r_blocks_count_hi; /* 0x154: Reserved blocks (high 32) */ __le32 s_free_blocks_count_hi; /* 0x158: Free blocks (high 32) */ __le16 s_min_extra_isize; /* 0x15C: Min extra inode size */ __le16 s_want_extra_isize; /* 0x15E: Wanted extra inode size */ __le32 s_flags; /* 0x160: Misc flags */ __le16 s_raid_stride; /* 0x164: RAID stride */ __le16 s_mmp_interval; /* 0x166: MMP check interval */ __le64 s_mmp_block; /* 0x168: MMP block location */ __le32 s_raid_stripe_width; /* 0x170: RAID stripe width */ __u8 s_log_groups_per_flex; /* 0x174: Flex BG size */ __u8 s_checksum_type; /* 0x175: Checksum algorithm */ __le16 s_reserved_pad; /* 0x176: Padding */ __le64 s_kbytes_written; /* 0x178: Written KB count */ // ... additional ext4 fields ... __le32 s_checksum; /* 0x3FC: Superblock checksum */};Critical Fields Explained:
| Field | Purpose | Typical Value |
|---|---|---|
s_magic | Identifies ext filesystem | 0xEF53 |
s_log_block_size | Block size encoding | 2 (4 KB = 1024 << 2) |
s_blocks_per_group | Blocks in each group | 32768 (4 KB blocks) |
s_inodes_per_group | Inodes in each group | 8192 (default) |
s_state | Clean (1) or Error (0) | 1 when cleanly unmounted |
s_feature_incompat | Required features | Varies by ext version |
s_journal_inum | Journal inode number | 8 (ext3/ext4) |
s_inode_size | Bytes per inode | 256 (ext4 default) |
Calculating Block Size:
uint32_t block_size = 1024 << s_log_block_size;
// s_log_block_size = 0 → 1024 bytes
// s_log_block_size = 1 → 2048 bytes
// s_log_block_size = 2 → 4096 bytes (most common)
// s_log_block_size = 4 → 65536 bytes (max)
While the original ext2 superblock used 264 bytes, ext4's full structure spans 1024 bytes. Fields beyond the original structure are guaranteed to be zero in older file systems, enabling forward compatibility while adding new features.
The ext superblock includes a sophisticated feature flag system that enables file system evolution while maintaining compatibility. Three categories of feature flags determine how the kernel handles unknown features:
1. Compatible Features (s_feature_compat)
Features that older kernels can safely ignore:
12345678910111213141516171819202122232425262728293031323334353637
// Compatible feature flags#define EXT4_FEATURE_COMPAT_DIR_PREALLOC 0x0001 // Dir preallocation#define EXT4_FEATURE_COMPAT_IMAGIC_INODES 0x0002 // AFS server inodes#define EXT4_FEATURE_COMPAT_HAS_JOURNAL 0x0004 // Has ext3 journal#define EXT4_FEATURE_COMPAT_EXT_ATTR 0x0008 // Extended attributes#define EXT4_FEATURE_COMPAT_RESIZE_INODE 0x0010 // Online resize support#define EXT4_FEATURE_COMPAT_DIR_INDEX 0x0020 // HTree directories#define EXT4_FEATURE_COMPAT_SPARSE_SUPER2 0x0200 // Sparse superblock v2 // Incompatible feature flags (kernel MUST understand)#define EXT4_FEATURE_INCOMPAT_COMPRESSION 0x0001 // Compression#define EXT4_FEATURE_INCOMPAT_FILETYPE 0x0002 // Dir entry file type#define EXT4_FEATURE_INCOMPAT_RECOVER 0x0004 // Journal needs recovery#define EXT4_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 // External journal device#define EXT4_FEATURE_INCOMPAT_META_BG 0x0010 // Meta block groups#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 // Extent-based allocation#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 // 64-bit block numbers#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 // Multi-mount protection#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 // Flex block groups#define EXT4_FEATURE_INCOMPAT_EA_INODE 0x0400 // Inodes for xattrs#define EXT4_FEATURE_INCOMPAT_DIRDATA 0x1000 // Data in dir entry#define EXT4_FEATURE_INCOMPAT_CSUM_SEED 0x2000 // Checksum seed#define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 // Large directories#define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 // Data in inode#define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 // Encryption // Read-only compatible feature flags#define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 // Sparse superblocks#define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 // Large file support#define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 // B-tree directories#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008 // >2GB inodes blocks#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 // GDT checksums#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 // >32K dir links#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 // Extended inode#define EXT4_FEATURE_RO_COMPAT_QUOTA 0x0100 // Quotas#define EXT4_FEATURE_RO_COMPAT_BIGALLOC 0x0200 // Cluster allocation#define EXT4_FEATURE_RO_COMPAT_METADATA_CSUM 0x0400 // Metadata checksums2. Incompatible Features (s_feature_incompat)
Features that change the on-disk format fundamentally:
3. Read-Only Compatible Features (s_feature_ro_compat)
Features safe to read but not write:
Mount Decision Logic:
int can_mount(struct ext4_super_block *sb, int readonly) {
// Check incompatible features
if (sb->s_feature_incompat & ~EXT4_FEATURE_INCOMPAT_SUPP) {
printk("Unknown incompatible features: %x\n",
sb->s_feature_incompat & ~EXT4_FEATURE_INCOMPAT_SUPP);
return -EINVAL; // Cannot mount at all
}
// Check read-only compatible features
if (!readonly &&
(sb->s_feature_ro_compat & ~EXT4_FEATURE_RO_COMPAT_SUPP)) {
printk("Unknown ro_compat features, mounting read-only\n");
// Force read-only mount
}
return 0; // Can proceed with mount
}
| File System | Typical Incompat Flags | Typical RO_Compat Flags |
|---|---|---|
| ext2 | filetype (optional) | sparse_super, large_file |
| ext3 | filetype, recover (if unclean) | sparse_super, large_file |
| ext4 (basic) | extents, flex_bg, filetype | sparse_super, large_file, huge_file, extra_isize |
| ext4 (full) |
|
|
Use tune2fs -l /dev/sdX | grep features to see enabled features. To enable/disable features: tune2fs -O ^feature,+feature /dev/sdX (filesystem must be unmounted for most changes).
Given the superblock's critical importance, ext file systems maintain multiple backup copies at predictable locations.
Sparse Superblock Feature:
The sparse_super feature (enabled by default) places backup superblocks only in select block groups:
Backup locations: 0, 1, 3, 5, 7, 9, 25, 27, 49, 81, 125, 243, 343, 625, ...
Calculating Backup Positions:
123456789101112131415161718192021222324252627282930313233343536373839
// Find all backup superblock locationsvoid find_backup_superblocks(uint32_t blocks_per_group, uint32_t total_groups) { printf("Backup superblocks at block groups:\n"); printf(" Group 0: block 0 (primary)\n"); printf(" Group 1: block %u\n", blocks_per_group); // Powers of 3 for (uint32_t p = 3; p < total_groups; p *= 3) { printf(" Group %u: block %llu\n", p, (uint64_t)p * blocks_per_group); } // Powers of 5 for (uint32_t p = 5; p < total_groups; p *= 5) { printf(" Group %u: block %llu\n", p, (uint64_t)p * blocks_per_group); } // Powers of 7 for (uint32_t p = 7; p < total_groups; p *= 7) { printf(" Group %u: block %llu\n", p, (uint64_t)p * blocks_per_group); }} // Example: 1TB filesystem, 4KB blocks// blocks_per_group = 32768, total_groups = 8192// Backup SB locations (block numbers):// Group 0: 0// Group 1: 32768// Group 3: 98304// Group 5: 163840// Group 7: 229376// Group 9: 294912// Group 25: 819200// Group 27: 884736// Group 49: 1605632// ...and so onRecovery Using Backup Superblock:
When the primary superblock is corrupted:
# Step 1: Find backup superblock locations
mke2fs -n /dev/sda1 # Dry run shows superblock locations
# Or use dumpe2fs on similar-sized filesystem
dumpe2fs /dev/reference | grep 'superblock'
# Step 2: Run e2fsck with backup superblock
e2fsck -b 32768 /dev/sda1 # Use backup at group 1
e2fsck -b 98304 /dev/sda1 # Or backup at group 3
# Step 3: If recovery succeeds, restore primary
# e2fsck automatically updates primary from backup
# Alternative: manually specify block size if needed
e2fsck -b 32768 -B 4096 /dev/sda1
Common Corruption Scenarios:
| Symptom | Likely Cause | Recovery |
|---|---|---|
| "Bad magic number" | Overwritten superblock | Use backup: e2fsck -b <backup> |
| "Bad superblock" | Corrupted fields | Same as above |
| Wrong block size detected | First KB corrupted | Specify block size: -B 4096 |
| Journal recovery fails | Journal corruption | Force: e2fsck -b <backup> -y |
| Multiple backup failures | Severe disk damage | Data recovery specialist |
Document your backup superblock locations immediately after creating a filesystem: mke2fs -n /dev/sdX or dumpe2fs /dev/sdX | grep superblock > ~/superblock_locations.txt. Store this information separately from the disk—in a crash, you won't have time to calculate.
Why Multiple Backups Matter:
Disk failures rarely corrupt just one sector. By placing backups according to the sparse_super pattern, ext ensures:
The superblock tracks file system state to detect unclean shutdowns and enforce periodic consistency checks.
State Fields:
// File system state values (s_state)
#define EXT4_VALID_FS 0x0001 // Cleanly unmounted
#define EXT4_ERROR_FS 0x0002 // Errors detected
#define EXT4_ORPHAN_FS 0x0004 // Orphan inodes present
// Error handling behavior (s_errors)
#define EXT4_ERRORS_CONTINUE 1 // Continue on errors
#define EXT4_ERRORS_RO 2 // Remount read-only
#define EXT4_ERRORS_PANIC 3 // Kernel panic
State Machine:
Mount Count and Time-Based Checks:
The superblock enforces periodic fsck runs:
| Field | Purpose | Typical Default |
|---|---|---|
s_mnt_count | Current mount count | Incremented each mount |
s_max_mnt_count | Max mounts before fsck | 20-40 (or -1 to disable) |
s_lastcheck | Last fsck timestamp | Updated by e2fsck |
s_checkinterval | Max seconds between fscks | 15552000 (6 months) |
The Mount Process Updates:
void ext4_update_superblock_on_mount(struct ext4_sb_info *sbi) {
struct ext4_super_block *sb = sbi->s_es;
// Clear VALID_FS flag (filesystem now "dirty")
sb->s_state &= ~EXT4_VALID_FS;
// Update mount statistics
sb->s_mnt_count++;
sb->s_mtime = get_current_time();
// Record mount point
strncpy(sb->s_last_mounted, mnt_point, 64);
// Sync superblock to disk
ext4_commit_super(sbi);
// Check if fsck is overdue
if (sb->s_mnt_count >= sb->s_max_mnt_count ||
get_current_time() > sb->s_lastcheck + sb->s_checkinterval) {
ext4_msg("Warning: maximal mount count reached, "
"running e2fsck is recommended");
}
}
Clean Unmount:
void ext4_update_superblock_on_unmount(struct ext4_sb_info *sbi) {
struct ext4_super_block *sb = sbi->s_es;
// Set VALID_FS flag (filesystem is now "clean")
sb->s_state |= EXT4_VALID_FS;
// Update write time
sb->s_wtime = get_current_time();
// Sync superblock to disk
ext4_commit_super(sbi);
}
With journaling, ext3/ext4 can recover from crashes by replaying the journal rather than scanning the entire filesystem. The mount/checkinterval fields become less critical—modern systems often set s_max_mnt_count to -1 (disabled) since journal recovery handles most corruption scenarios.
Several command-line tools interact with ext superblocks for administration, analysis, and recovery.
dumpe2fs: Superblock Inspector
# Display all superblock information
dumpe2fs /dev/sda1
# Show only superblock (skip group descriptors)
dumpe2fs -h /dev/sda1
# Example output (abbreviated):
Filesystem volume name: root
Last mounted on: /
Filesystem UUID: a1b2c3d4-e5f6-7890-abcd-ef1234567890
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index
filetype extent flex_bg sparse_super large_file
huge_file dir_nlink extra_isize
Filesystem flags: signed_directory_hash
Block count: 244190646
Reserved block count: 12209532 (5%)
Free blocks: 89234567
Free inodes: 58901234
First block: 0
Block size: 4096
Fragment size: 4096
Blocks per group: 32768
Inodes per group: 8192
Inode size: 256
Journal inode: 8
Journal size: 128M
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
# tune2fs: Modify superblock parameters# ===================================== # Set volume labeltune2fs -L "MyVolume" /dev/sda1 # Set UUIDtune2fs -U random /dev/sda1 # Enable/disable featurestune2fs -O extent,dir_index /dev/sda1 # Enabletune2fs -O ^extent /dev/sda1 # Disable # Change mount count limitstune2fs -c 30 /dev/sda1 # fsck every 30 mountstune2fs -c 0 /dev/sda1 # Disable mount-based fscktune2fs -i 6m /dev/sda1 # fsck every 6 monthstune2fs -i 0 /dev/sda1 # Disable time-based fsck # Change error behaviortune2fs -e remount-ro /dev/sda1 # Remount RO on errortune2fs -e panic /dev/sda1 # Panic on errortune2fs -e continue /dev/sda1 # Continue on error # Set reserved block percentage (for root)tune2fs -m 5 /dev/sda1 # 5% reservedtune2fs -m 1 /dev/sda1 # 1% for non-system drives # e2fsck: Check and repair# ======================== # Normal checke2fsck -f /dev/sda1 # Force check (even if clean) # Use backup superblocke2fsck -b 32768 /dev/sda1 # Group 1 backupe2fsck -b 98304 -B 4096 /dev/sda1 # Group 3, specify block size # Automatic repair (dangerous)e2fsck -y /dev/sda1 # Yes to all repairse2fsck -p /dev/sda1 # Auto-fix safe problems # mke2fs: Create filesystem (set initial superblock)# ================================================== # Standard ext4mke2fs -t ext4 /dev/sda1 # Custom inode ratio (more inodes for small files)mke2fs -t ext4 -i 4096 /dev/sda1 # 1 inode per 4KB # Specific featuresmke2fs -t ext4 -O ^metadata_csum,^64bit /dev/sda1 # Set volume label during creationmke2fs -t ext4 -L "DataDrive" /dev/sda1 # Show what would be created (dry run)mke2fs -n /dev/sda1debugfs: Low-Level Superblock Access
# Open filesystem for examination
debugfs /dev/sda1
# Show superblock parameters
debugfs: show_super_stats
# Dump specific superblock field
debugfs: stats
# Read backup superblock
debugfs -s 1 /dev/sda1 # Use superblock from group 1
# Examine specific block (hex dump)
debugfs: block_dump 0 # Dump block 0 (boot + start of SB)
Using dd for Manual Superblock Backup:
# Backup primary superblock to file
dd if=/dev/sda1 of=superblock_backup.bin bs=1024 skip=1 count=1
# Restore superblock (DANGEROUS - know what you're doing)
dd if=superblock_backup.bin of=/dev/sda1 bs=1024 seek=1 count=1
Most superblock modifications require an unmounted filesystem. Running tune2fs or e2fsck on a mounted filesystem risks severe corruption. The exception: tune2fs -l (read-only display) is safe on mounted filesystems.
The superblock has grown significantly across ext versions, always maintaining backward compatibility.
ext2 Original Superblock (1993):
ext3 Additions (2001):
ext4 Additions (2008+):
| Offset | Size | Field | Introduced |
|---|---|---|---|
| 0x00 | 4 | s_inodes_count | ext2 rev0 |
| 0x38 | 2 | s_magic | ext2 rev0 |
| 0x3A | 2 | s_state | ext2 rev0 |
| 0x54 | 4 | s_first_ino | ext2 rev1 |
| 0x5C | 4 | s_feature_compat | ext2 rev1 |
| 0xD0 | 16 | s_journal_uuid | ext3 |
| 0xE0 | 4 | s_journal_inum | ext3 |
| 0x150 | 4 | s_blocks_count_hi | ext4 |
| 0x168 | 8 | s_mmp_block | ext4 |
| 0x174 | 1 | s_log_groups_per_flex | ext4 |
| 0x175 | 1 | s_checksum_type | ext4 |
| 0x3FC | 4 | s_checksum | ext4 |
Forward and Backward Compatibility:
// When ext4 reads an ext2 superblock:
if (sb->s_rev_level == 0) {
// Revision 0: assume basic defaults
sbi->s_inode_size = 128;
sbi->s_first_inode = 11;
// Feature flags don't exist, assume none
} else {
// Revision 1+: read extended fields
sbi->s_inode_size = sb->s_inode_size;
sbi->s_first_inode = sb->s_first_ino;
// Check feature compatibility
check_feature_flags(sb);
}
// Unused fields in older filesystems are zero
// ext4 safely reads them without special handling
Upgrade Path:
# Upgrade ext2 → ext3 (add journal)
tune2fs -j /dev/sda1 # Creates journal inode
# Upgrade ext3 → ext4 (enable extents)
tune2fs -O extent,uninit_bg /dev/sda1
e2fsck -fD /dev/sda1 # Rebuild with new features
# Note: Existing files don't automatically convert
# Only new files use new features
Despite mounting as '-t ext4', the actual feature set depends on superblock flags. Use tune2fs -l /dev/sdX | grep 'Filesystem features' to see exactly what features are enabled. An "ext4" mount might actually be using ext3-level features if the filesystem was never upgraded.
The superblock is the most critical data structure in any ext file system, containing the complete specification needed to interpret all other structures.
Next Up: Ext3 Journaling
With superblock fundamentals understood, we'll explore ext3's revolutionary contribution: journaling. The journal uses a dedicated inode (number 8) and write-ahead logging to guarantee consistent recovery after crashes, eliminating the hours-long fsck operations that plagued ext2.
You now have deep understanding of the ext superblock—its structure, fields, redundancy strategy, and the tools for working with it. This knowledge is essential for file system administration, recovery operations, and understanding how Linux mounts and validates ext filesystems.