A single file write isn’t one operation to the disk — it’s several: update the data blocks, the inode, the free-space bitmap, maybe a directory entry. Lose power between them and the filesystem is left in a contradictory state. A journal is how ext4 turns “several steps” back into something that’s all-or-nothing.
Why a Crash Corrupts
Appending to a file touches multiple structures that must stay consistent:
1. write the new data blocks
2. mark those blocks used in the bitmap
3. update the inode's size and block pointersCrash after step 2 but before 3, and the bitmap says “used” while no inode points
there — leaked space. Crash between 1 and 2, and the inode may point at blocks the
bitmap thinks are free, to be handed to another file later — corruption. The
old fix was fsck scanning the entire disk on boot, which takes minutes to hours
on a large volume.
Write-Ahead: Say It Before You Do It
A journal is a reserved on-disk area where the filesystem first records what it is about to do, then does it. The sequence:
1. write the intended changes to the journal ("transaction")
2. mark the transaction committed (a commit record)
3. apply the changes to their real locations ("checkpoint")
4. mark the journal entry freeThe commit record in step 2 is the atomic switch. After a crash, recovery just replays the journal:
transaction committed? ──yes──▶ replay it (redo the changes)
──no───▶ discard it (it never happened)Either the operation fully happened or it fully didn’t. Recovery reads a small journal, not the whole disk — seconds, not hours.
The Three Modes of ext4
Journaling everything is safe but doubles writes — data goes to the journal and its final home. ext4 lets you choose what’s protected:
journal metadata + data both journaled safest, slowest
ordered metadata journaled; data written
before the metadata commit default, good balance
writeback metadata journaled; data unordered fastest, can show stale
data after a crashOrdered mode (the default) is the clever compromise: it doesn’t journal file data, but it forces data blocks to disk before committing the metadata that points to them. So metadata never references garbage — you won’t see another file’s old contents — without paying to journal data twice.
The Limit
A journal guarantees the filesystem is consistent, not that your application’s
data is. A committed transaction can still represent a half-written file from the
app’s point of view. That’s what fsync() is for — and why databases call it
religiously before reporting a write durable.
Takeaways
- Filesystem operations touch several structures; a crash between them corrupts the volume.
- A journal is a write-ahead log: record the intent, commit atomically, then apply — so recovery replays or discards whole transactions.
- ext4’s ordered mode protects metadata and orders data before the commit, balancing safety and speed without journaling data twice.
- Journaling protects filesystem consistency, not application durability — that’s
still on
fsync().