#[non_exhaustive]pub enum Anomaly {
LinkCountTooLow {
ino: u32,
stored: u16,
observed: u32,
},
LinkCountTooHigh {
ino: u32,
stored: u16,
observed: u32,
},
DanglingEntry {
parent_ino: u32,
child_ino: u32,
observed: u32,
},
WrongDotDot {
dir_ino: u32,
claims: u32,
actual_parent: u32,
},
BogusEntry {
parent_ino: u32,
child_ino: u32,
name: Vec<u8>,
},
BlockGroupFreeCountDrift {
group_index: u32,
stored_blocks: u32,
observed_blocks: u32,
stored_inodes: u32,
observed_inodes: u32,
},
SuperblockFreeCountDrift {
stored_blocks: u64,
observed_blocks: u64,
stored_inodes: u32,
observed_inodes: u32,
},
DuplicateDirentForDirInode {
ino: u32,
dirents: Vec<(u32, String)>,
},
DirBlockChecksumMismatch {
dir_ino: u32,
logical_block: u64,
htree: bool,
},
UnreadableDirectory {
ino: u32,
reason: String,
},
}Expand description
One problem found by audit. Each variant carries the inode or
path needed to act on the finding.
#[non_exhaustive]: the audit learns new findings, and a match on
this outside the crate needs a _ arm so a new one does not break it.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
LinkCountTooLow
A directory entry references an inode whose i_links_count is
less than the observed reference count. Stored value is too
low — fsck would increase it to observed.
LinkCountTooHigh
Inode’s i_links_count is greater than the observed reference
count. Stored value is too high — fsck would decrease it.
DanglingEntry
Dangling directory entry: a dir entry points to an inode with
i_links_count == 0 or one we couldn’t read.
observed is how many dirents reference child_ino from the
audit’s directory walk. For the readable-but-zero-links case
the rescue path writes observed into the inode’s
i_links_count (it’s the same fix as LinkCountTooLow from
stored=0). For the unreadable case we synthesise
observed = 0 so the rescue is correctly refused — there’s no
safe way to repair an inode we can’t read without orphan-list
or /lost+found machinery.
WrongDotDot
A directory’s .. entry does not point at its true parent.
BogusEntry
A directory entry inside parent_ino claims its target
(child_ino) is a directory, but the target inode’s mode bits
are not S_IFDIR. Read failures on the child are surfaced as
DanglingEntry from the inodes phase instead. Carrying both
inodes lets a repair pass either rewrite the dirent’s
file_type byte (when the child is a valid non-dir) or
unlink the dirent.
Carries the dirent’s name so the repair pass can target the
exact record by (parent, name) — necessary when the parent has
multiple hardlinks to the same inode and only one of them has
the wrong file_type byte. Stored as raw bytes since ext4
dirent names are not required to be UTF-8.
BlockGroupFreeCountDrift
One block group’s free-block / free-inode counters drift from the bitmap reality. Either the bitmap claims fewer free bits than the descriptor says (over-count) or more (under-count). Common after crashes that interrupted bitmap+descriptor pairs mid-write. Repair walks the bitmap, recomputes the truth, and patches the descriptor (incl. checksum when metadata_csum is on).
Fields
SuperblockFreeCountDrift
Superblock free-block / free-inode totals don’t match the sum
across all group descriptors’ (post-bitmap) counts. Independent
of BlockGroupFreeCountDrift: the per-group descriptors might
agree with their bitmaps but the SB total still disagree (e.g.
a torn write of just the SB block). Repair recomputes from the
bitmaps and writes the SB.
DuplicateDirentForDirInode
Multiple directory entries reference the same directory inode.
Illegal — directories can have only one parent dirent (plus . and ..).
Caused by an inode-allocator bug in early apply_mkdir (fixed) but
the on-disk wreckage remains until repair runs.
Fields
DirBlockChecksumMismatch
A directory block’s checksum does not match its contents: e2fsck’s
“directory passes checks but fails checksum” for a linear block, and
“root node fails checksum” / “internal node fails checksum” when
htree is set and the block is an htree index.
Only reported on metadata_csum volumes, and only for a block that
carries a checksum to check. A repair never restamps a block whose
checksum fails unless it is repairing this finding (#344): the
repair pass fixes the checksum of a linear block that passes the
structural checks, as e2fsck does, and leaves an htree index, which
e2fsck rebuilds, reported and untouched.
UnreadableDirectory
A directory the walk could not read: its inode does not verify, or
its entries cannot be listed (an extent tree that does not parse, a
block that cannot be read). Nothing beneath it was examined, so the
audit cannot call the volume clean (#445). reason is the error the
read failed with.
Not repairable: e2fsck clears such an inode (Inode 2 has corrupt extent header. Clear inode?), which loses everything beneath it,
and that is not a decision this repair pass makes.