The
The principle is almost embarrassingly simple, and it is one of the most important ideas in systems: before you touch the real structures, write down what you are about to do in a dedicated on-disk log (the journal). Only once that intention is safely recorded do you go and modify the actual inodes, bitmaps, and data in place. If you crash midway, recovery reads the log and either replays the intention (if it was fully recorded) or discards it (if it wasn't). Either way you end up in a state that could have happened — never a torn one. ext3, ext4, XFS, JFS, and NTFS all live by this.
A journaled update is a transaction that moves through three phases. The magic is entirely in the ordering barrier between phase 2 and phase 3.
Recovery is then trivial and fast: after a crash, scan the journal. For every transaction that has a valid commit
record, replay it (re-do the checkpoint) — this is safe even if it already partly happened,
because re-writing the same blocks is idempotent. Any transaction without a commit record is
thrown away as if it never began. Crucially, recovery time is proportional to the journal size (a few
megabytes), not the disk size — that is the whole win over
Watch the barrier. The commit record must not hit the disk until the journal-write blocks are all durable — otherwise recovery might trust a commit for a transaction whose data never arrived. This single ordering constraint (enforced with the write barriers of a later lesson) is what makes the whole scheme correct.
The model below is a miniature journaling file system. Several transactions sit in the journal; some have a commit record, some were interrupted by the crash and do not. Recovery replays only the committed ones onto the "disk." Notice the uncommitted transaction is silently dropped — exactly the behaviour that keeps the file system consistent.
Journaling has an obvious price: every journaled block is written twice — once to the log, once to its real home. For a file system that logged all data, that halves write bandwidth. So real systems offer three modes trading safety against that cost. ext3/ext4 name them exactly:
| Mode | What is journaled | Trade-off |
|---|---|---|
| data (journal) | metadata and data | safest; every data byte written twice |
| ordered (default) | metadata only; data forced to disk before the metadata commits | fast + safe: no stale-data exposure |
| writeback | metadata only; data written whenever | fastest; a crash can expose stale bytes in a newly-grown file |
Almost everyone runs ordered mode. It journals only metadata (so the double-write hits just the small structures, not your gigabytes of data), yet by forcing the data blocks to their final home before the metadata that points at them is committed, it guarantees a committed inode never points at a block full of someone else's old bytes. Metadata-only journaling is the default of the whole industry for exactly this reason.
Committing a transaction per
Because the commit record is the one place the scheme leans directly on the hardware's single-block atomicity. The whole protocol reduces "did this multi-block transaction happen?" to "did this one block — the commit record — make it to disk?" A single block is exactly the thing the disk promises to write all-or-nothing, so the answer is never ambiguous: either the commit block is there (replay) or it isn't (discard). If the commit needed two blocks you would be back to the original problem — a torn commit — one level up. This is a recurring trick in systems: build a big atomic action by funnelling its "did it happen?" decision through a single atomic write. (Real implementations also add a checksum so a commit record that is present but corrupt is treated as absent.)
A journaled file system will never boot into a corrupt state — but that does not mean your last