C++ / a working model

146 / 163   ·   C11   ·   8 min

Crash Consistency: FSCK and Journaling

Keep this sentence

File systems keep inodes, bitmaps and data blocks on disk; one operation often needs several writes. A crash can leave a partial update and inconsistency. This chapter originally explains fsck-style later scanning plus journaling (write-ahead logging) that recovers quickly with modest extra work.

In this lesson
  1. The Problem of Crashes During Persistent Updates
  2. Repairing After the Fact with a Checker
  3. Journaling: Record Intent Before Real Updates
  4. Common Journaling Modes
  5. Example
  6. Exercise

Official chapter PDF

The Problem of Crashes During Persistent Updates

A disk finishes only one write at a time. Appending a block requires changing the inode, the data bitmap and the new data block. A crash between those writes can leave a bitmap-inode mismatch, a leaked block or garbage contents. Ideally the whole operation would finish atomically, moving the on-disk image from one consistent picture to another.

Repairing After the Fact with a Checker

Early designs let inconsistencies happen and ran a tool such as fsck at reboot. The checker walks every inode, bitmap and directory, finds mismatches and repairs them. The method is easy to implement, yet a full scan of a large disk takes a long time and the file system stays unavailable during recovery.

Journaling: Record Intent Before Real Updates

Journaling first appends the complete intent of an operation into a dedicated log and forces it to disk, then updates the real inodes, bitmaps and data. After a crash the system only scans the log, replays committed transactions or discards uncommitted ones, restoring consistency quickly without a full-disk walk.

Common Journaling Modes

Data journaling puts both user data and metadata into the log, giving the strongest guarantees at the cost of extra writes. Metadata journaling logs only metadata while data goes straight to its final location, so a crash may expose stale contents. Ordered mode forces data to disk before the matching metadata. Implementations trade performance, space and safety.

Pitfalls

  • Believing the disk can atomically finish several writes
  • Not forcing the journal to stable storage before the commit record, leaving a torn log
  • Fixing only metadata while users can still read garbage data

Run an example

Minimum C11 · complete program · Download .c

#include <stdio.h>

int main(void) {
    printf("Tiny file-system crash-consistency demo\n");
    printf("Operation: append one data block (update inode, bitmap, data)\n\n");
    printf("Crash after 1 write:\n");
    printf("  data only     -> write lost, still consistent\n");
    printf("  inode only    -> pointer to garbage, bitmap mismatch\n");
    printf("  bitmap only   -> leaked block, no owner\n\n");
    printf("Crash after 2 writes:\n");
    printf("  inode+bitmap  -> metadata OK, garbage data\n");
    printf("  inode+data    -> bitmap mismatch\n");
    printf("  bitmap+data   -> leaked block\n\n");
    printf("Journaling solution: write transaction to log, commit, then checkpoint.\n");
    printf("Recovery: replay committed transactions only.\n");
    return 0;
}

Compile locally

gcc -std=c11 -Wall -Wextra -Wpedantic -Werror ostep-42-journaling.c -o example && ./example

Expected result

Tiny file-system crash-consistency demo
Operation: append one data block (update inode, bitmap, data)

Crash after 1 write:
  data only     -> write lost, still consistent
  inode only    -> pointer to garbage, bitmap mismatch
  bitmap only   -> leaked block, no owner

Crash after 2 writes:
  inode+bitmap  -> metadata OK, garbage data
  inode+data    -> bitmap mismatch
  bitmap+data   -> leaked block

Journaling solution: write transaction to log, commit, then checkpoint.
Recovery: replay committed transactions only.

CHECK YOUR UNDERSTANDING

Close the answer. Explain it.

If an append writes the inode and the data block but not the bitmap, what inconsistency appears on disk? How would fsck versus journaling handle it?

Show a reference answer

The inode claims a block that the bitmap still marks free. fsck would scan and set the bitmap bit to match the inode. Journaling recorded the whole transaction first, so recovery either replays all three updates together or rolls them all back, never leaving that half-done state.

Check the sources

Drafts and official chapters change. The version mark is only the example’s minimum.

Back to the catalog