pub struct Superblock {Show 40 fields
pub inodes_count: u32,
pub blocks_count: u64,
pub free_blocks_count: u64,
pub free_inodes_count: u32,
pub r_blocks_count: u64,
pub first_data_block: u32,
pub log_block_size: u32,
pub blocks_per_group: u32,
pub inodes_per_group: u32,
pub magic: u16,
pub state: u16,
pub errors_behavior: u16,
pub minor_rev_level: u16,
pub rev_level: u32,
pub inode_size: u16,
pub first_inode: u32,
pub feature_compat: u32,
pub feature_incompat: u32,
pub feature_ro_compat: u32,
pub uuid: [u8; 16],
pub volume_name: String,
pub last_mounted: String,
pub desc_size: u16,
pub reserved_gdt_blocks: u16,
pub backup_bgs: [u32; 2],
pub hash_seed: [u32; 4],
pub default_hash_version: u8,
pub checksum_seed: u32,
pub journal_inode: u32,
pub last_orphan: u32,
pub mtime: u32,
pub wtime: u32,
pub mnt_count: u16,
pub max_mnt_count: u16,
pub lastcheck: u32,
pub checkinterval: u32,
pub creator_os: u32,
pub def_resuid: u16,
pub def_resgid: u16,
pub raw: Vec<u8>,
}Expand description
Parsed in-memory representation of the ext4 superblock.
Field names follow struct ext4_super_block in the kernel.org format
documentation (s_ prefix dropped).
Fields§
§inodes_count: u32§blocks_count: u64§free_blocks_count: u64§free_inodes_count: u32§r_blocks_count: u64s_r_blocks_count (lo at 0x08, hi at 0x154 — 64-bit on
INCOMPAT_64BIT volumes). Blocks reserved for the superuser
— explains the gap between free_blocks and what df
reports as available to a normal user.
first_data_block: u32§log_block_size: u32§blocks_per_group: u32§inodes_per_group: u32§magic: u16§state: u16s_state (0x3A). EXT4_VALID_FS = cleanly unmounted. Any other
value means the FS was mounted and not cleanly unmounted (dirty)
or that the kernel marked the FS as having errors.
errors_behavior: u16s_errors (0x3C). Kernel error policy: 1=continue, 2=remount-ro,
3=panic. Informational from a Swift host’s POV but useful in
diagnostics output.
minor_rev_level: u16s_minor_rev_level (0x3E). Bumped by filesystem admin tools for minor format
tweaks within a major rev_level.
rev_level: u32§inode_size: u16§first_inode: u32s_first_ino (0x54, dynamic-rev only). First non-reserved
inode number; defaults to 11 on rev_level=1+ filesystems.
feature_compat: u32§feature_incompat: u32§feature_ro_compat: u32§uuid: [u8; 16]§volume_name: String§last_mounted: Strings_last_mounted (0x88, 64 bytes). Last directory the FS was
mounted at — handy for diagnostics (“when was this disk last
in another machine?”).
desc_size: u16§reserved_gdt_blocks: u16s_reserved_gdt_blocks — blocks held back after the group
descriptor table so the filesystem can be grown online.
They sit between the GDT and the block bitmap in every group that carries a superblock backup, and they are not free space: anything that rebuilds a block bitmap has to mark them used or the next allocation writes over the filesystem’s own room to expand.
backup_bgs: [u32; 2]s_backup_bgs — the only two groups carrying backups when
SPARSE_SUPER2 is set. Meaningless without that feature.
hash_seed: [u32; 4]§default_hash_version: u8§checksum_seed: u32§journal_inode: u32§last_orphan: u32s_last_orphan (0xE8). Head of the orphan-inode list — inodes
whose link count reached zero while still open. The kernel
inserts unlink-while-open targets here so that, on the next
mount, recovery can reclaim them. Each inode’s i_dtime field
is overloaded to point at the next orphan in the chain; the
chain terminates with a zero dtime.
mtime: u32s_mtime (0x2C). Timestamp the FS was last mounted.
wtime: u32s_wtime (0x30). Timestamp the FS was last written to.
mnt_count: u16s_mnt_count (0x34). Mounts since last fsck.
max_mnt_count: u16s_max_mnt_count (0x36). Forced fsck after this many mounts;
0 disables.
lastcheck: u32s_lastcheck (0x40). Timestamp of the last fsck pass.
checkinterval: u32s_checkinterval (0x44). Seconds between forced fscks; 0
disables time-based forced fsck.
creator_os: u32s_creator_os (0x48). 0=Linux, 1=Hurd, 2=Masix, 3=FreeBSD,
4=Lites.
def_resuid: u16s_def_resuid (0x50). UID with access to reserved blocks.
def_resgid: u16s_def_resgid (0x52). GID with access to reserved blocks.
raw: Vec<u8>Implementations§
Source§impl Superblock
impl Superblock
Sourcepub fn read<D: BlockDevice + ?Sized>(dev: &D) -> Result<Self>
pub fn read<D: BlockDevice + ?Sized>(dev: &D) -> Result<Self>
Read and parse the superblock from a block device.
pub fn parse(raw: Vec<u8>) -> Result<Self>
Sourcepub fn is_clean(&self) -> bool
pub fn is_clean(&self) -> bool
Whether the filesystem was cleanly unmounted. false here means
the FS was not cleanly unmounted and a journal replay (or fsck)
is required before writes are safe. Read-only consumers can
still mount a dirty FS; callers that intend to write should
surface this to the user and either run fsck or refuse to
mount read-write.
Sourcepub fn group_has_super(&self, g: u64) -> bool
pub fn group_has_super(&self, g: u64) -> bool
Whether block group g carries a superblock and group-descriptor
backup.
Three layouts, and the filesystem’s own flags decide which:
SPARSE_SUPER2: group 0, and the two groups named bys_backup_bgs. Nothing else.SPARSE_SUPERclear: every group. This is the old ext2 layout, and the one that costs most to get wrong — assuming the sparse rule leaves real backups looking like free space.- otherwise: the classic sparse rule — groups 0 and 1, and every power of 3, 5 or 7.
Answering unconditionally with the classic rule is wrong in both
of the first two cases, and wrong in the direction that matters:
on a filesystem without SPARSE_SUPER it reports “no backup here”
for groups that have one, so a rebuilt bitmap offers the backup
superblock and its descriptor table as free blocks.
Sourcepub fn descs_per_block(&self) -> u64
pub fn descs_per_block(&self) -> u64
Group descriptors per descriptor-table block.
Sourcepub fn first_meta_bg(&self) -> u64
pub fn first_meta_bg(&self) -> u64
s_first_meta_bg (0x104): the first meta group whose descriptors
live in the meta group rather than the contiguous table. Zero
without META_BG.
Sourcepub fn descriptor_location(&self, group: u64) -> (u64, usize)
pub fn descriptor_location(&self, group: u64) -> (u64, usize)
Where group group’s descriptor lives: the block, and the byte
offset within it (#73). The primary copy; backups are elsewhere.
Sourcepub fn group_head_metadata_blocks(&self, group: u64) -> u64
pub fn group_head_metadata_blocks(&self, group: u64) -> u64
How many blocks at the head of group are superblock copy,
descriptor blocks and reserved GDT blocks: what precedes any bitmap
or inode table the group holds.
Sourcepub fn unsigned_hash(&self) -> bool
pub fn unsigned_hash(&self) -> bool
Whether directory names are hashed as unsigned bytes: s_flags
(0x160) carries EXT2_FLAGS_UNSIGNED_HASH (0x2). See
crate::hash::effective_version.
Sourcepub fn block_size(&self) -> u32
pub fn block_size(&self) -> u32
Block size in bytes: 1024 << log_block_size.
Sourcepub fn filesystem_bytes(&self) -> Option<u64>
pub fn filesystem_bytes(&self) -> Option<u64>
blocks_count * block_size, or None when the product overflows
a u64 – which no real filesystem does, so a caller refuses it
rather than saturating to a bound that admits anything.
Sourcepub fn check_fits_device(&self, device_bytes: u64) -> Result<()>
pub fn check_fits_device(&self, device_bytes: u64) -> Result<()>
THE FILESYSTEM FITS ITS DEVICE (#321), the kernel’s “block count
exceeds size of device”. Every bound that reads blocks_count
otherwise trusts a size nothing checked: a superblock claiming
2^32 blocks on a few megabytes let read_all ask for terabytes.
A device larger than the filesystem is normal (a partition, an
FSKit volume); a smaller one is a truncated or forged image.
Sourcepub fn block_group_count(&self) -> u64
pub fn block_group_count(&self) -> u64
Number of block groups.
Counted from s_first_data_block (format documentation: “at least 1
for 1k-block filesystems”): on a 1 KiB-block filesystem block 0 is the
boot block and the
groups start at block 1. Dividing the whole of s_blocks_count
gave one group too many whenever it was one past a multiple of
s_blocks_per_group, and the phantom group’s descriptor – zeros –
failed its checksum and refused a volume Linux mounts (#86). The
rest of the crate (alloc::blocks_in_group, the block-to-group
mapping) already subtracted it.