= File-system journaling
<File-system journaling> makes a group of related <file system> updates recoverable after a crash by recording them in a journal before changing their final storage locations. The useful promise is <file-system crash consistency>: after <journal replay>, a protected <file-system transaction> has taken effect completely or has not taken effect. <File-system transaction durability> adds a different promise: an acknowledged update survives the crash. The protected group can contain only <file metadata>, or both <file metadata> and <file data blocks>, depending on the <file-system journaling mode>.
Consider a tiny <file> containing `ABCD` in four-<byte> <file data block> 7. Its <inode> records size 4 and a reference to block 7. Appending `EFGH` in previously free block 9 requires three new stored records: $I$, the <inode> with size 8 and references to blocks 7 and 9; $B$, the <block allocation bitmap> marking block 9 allocated; and $D$, <file data block> 9 containing `EFGH`. An <inode> reference to a block still marked free lets a later allocation overwrite live contents; allocating a block without recording its owner can leak space. Even mutually consistent <file metadata> can expose stale contents if $D$ has not reached storage. Chapter 42 of <Operating Systems: Three Easy Pieces by Remzi H. Arpaci-Dusseau and others/Crash Consistency: FSCK and Journaling> (section 42.1, pp. 2–4) develops this three-record append problem; the names, block numbers and tiny contents here are original teaching choices.
The first diagram protects all three records with <write-ahead logging>. Each <journal payload> record identifies a final destination and its complete new contents. A <storage flush> makes the complete <journal payload> durable before a separate <journal commit record> is written and made durable. Only then may a <journal checkpoint> copy the records to their final locations. The journal remains available until those copies have themselves passed a <storage flush>; it can then be retired and its space reused. <Journal replay> repairs an interrupted <journal checkpoint> using the retained new contents.<3.6. Journal (jbd2) by The kernel development community>{ref}
\Image[/file-system-journal-transaction-timeline.png]
{title=<Write-ahead logging> separates durable <journal commit records> from <journal checkpoints> and safe journal reuse}
These are persistence dependencies, not a claim that issuing writes in this order is sufficient. A device can report completion while its volatile <memory cache> still holds the only copy. The <Linux kernel> documents both flushing earlier completed requests and making completion of a particular request depend on persistence. The timeline uses separate <storage flushes> to make the dependencies explicit; an implementation can use equivalent device-supported operations. A commit write can persist before its <storage flush> returns: recovery uses the actual durable marker, while acknowledgment waits for successful completion.<Explicit volatile write back cache control by The kernel development community>{ref}
The appeal is that recovery knows exactly which updates to finish. It does not have to infer a user's intended contents from contradictory <inodes> and <block allocation bitmaps>. The cost includes writing the <journal payload> as well as its final copies and waiting for persistence boundaries. The journal records a recent transition, not a historical collection of recoverable <files>; <file-system journaling> is not a <file-system backup>.
Back to article page