Β§45.4–45.9Using Checksums: Misdirected Writes, Lost Writes, Scrubbing, and Overheads

Part III OSTEP pp. 593–596 Β· ~11 min read

  • misdirected write
  • lost write
  • disk scrubbing

With a checksum layout chosen, we can put checksums to work β€” and then meet two sneakier failures they don’t yet catch.

45.4 Using Checksums

Verifying a block is a three-step ritual on every read: fetch the stored checksum Cs(D)C_s(D), recompute the checksum Cc(D)C_c(D) over the bytes you got back, and compare.

Using a checksum on read: fetch the stored checksum, recompute it over the retrieved bytes, and compare.
read block D, then check itDthe data blockCs(D)stored (from disk)

1Read the block and its stored checksum

When reading block D, the client also reads the checksum saved with it, the stored checksum Cs(D).

step 1 / 4

If they match, the data is (almost certainly) intact. If not, corruption is detected β€” recover from a redundant copy if you have one, else return an error. A checksum only detects; without another copy of the block, detection just tells you precisely how out of luck you are.

45.5 A New Problem: Misdirected Writes

Basic checksums assume the right data ends up in the right place. But a disk or RAID controller can commit a misdirected write : the data is written correctly, just to the wrong location β€” block Dx lands at address y (clobbering Dy), or even on the wrong disk entirely. The block that lands is internally consistent, so its checksum happily matches β€” the fault is purely one of place.

The fix adds a physical ID to each block’s stored info: its own disk number and offset. On read, the client checks that the stored address matches the address it meant to read:

A misdirected write lands valid data in the wrong place. The block’s own stored address (physical ID) is what reveals the mistake on read.
each block carries its checksum + its own address (disk, block)Disk 1C[D0]disk=1block=0D0C[D1]disk=1block=1D1C[D2]disk=1block=2D2Disk 0C[D0]disk=0block=0D0C[D1]disk=0block=1D1C[D2]disk=0block=2D2

1Store each block’s own address

On every write, save the checksum AND a physical ID β€” the block’s disk number and offset β€” next to the data.

step 1 / 3

That extra redundancy β€” the disk and block numbers repeated next to each block β€” is worthless on a perfect disk, but it’s exactly what turns a silent misplacement into a detected corruption.

45.6 One Last Problem: Lost Writes

The nastiest failure is the lost write : the device reports a write as complete but never persists it, leaving the old contents in place. Now both of our defenses are useless β€” the stale block still matches its own old checksum, and its physical ID is still correct:

A lost write leaves stale data behind. Both block-local defenses match the old block, so detection needs a checksum kept elsewhere (or a read-after-write).
client wrote a NEW Dβ€² β€” but the write was lostold D(stale)C(old)id okdevice replied β€œdone”, yet never persisted Dβ€²

1The write is acknowledged but lost

The client writes new contents Dβ€². The device reports success, but never actually persists it β€” the disk still holds the OLD D.

step 1 / 3

The classic brute-force answer is a write verify (read-after-write): read the block straight back to confirm it reached the surface β€” safe, but it doubles write I/O. Sun’s ZFS takes a cheaper route: store each block’s checksum in its inode and indirect blocks. The write updates the inode’s checksum, so a lost data write no longer matches it. Only if the writes to both the inode and the data are lost together does the scheme fail β€” unlikely, though not impossible.

45.7 Scrubbing

When do all these checksums actually get checked? At access time β€” but most data is read rarely, so it would sit unverified while bit rot silently corrupts every copy. Disk scrubbing closes that gap: the system periodically reads through every block and re-verifies its checksum, typically on a nightly or weekly schedule. (In the failure studies, most latent sector errors were found precisely this way.)

45.8 Overheads of Checksumming

Nothing is free. Checksumming’s costs split into the usual two kinds β€” space and time:

The price of checksumming: small in space, more noticeable in time.
kinddetail
disk spacespaceβ‰ˆ 0.19% β€” an 8-byte checksum per 4 KB data block
memoryspaceroom for checksums alongside the data while checking β€” short-lived if discarded right after use
CPUtimecompute the checksum on every store AND every read
extra I/Otimewhen checksums live apart from the data, plus background scrubbing (tunable β€” schedule it at night)
Dotted-underlined cells have explanations β€” click one.

Space is nearly a rounding error; the time cost (CPU per block, plus any extra I/O for separated checksums and scrubbing) is the one you actually tune β€” hence the copy-and-checksum fusion and the scheduled, off-peak scrubs.

45.9 Summary β€” every defense closes one gap

Each layer of protection catches a failure the previous one couldn’t. Reading the table top to bottom is the whole chapter in miniature:

The whole chapter in one table: each defense (top to bottom) closes one more gap. βœ“ = detected, βœ— = slips through. Recovery of any detected fault still relies on redundancy.
latent sector errorblock corruptionmisdirected writelost write
in-drive ECCβœ“ returns errorβœ—βœ—βœ—
+ basic checksumβœ“βœ“ Cs β‰  Ccβœ—βœ—
+ physical IDβœ“βœ“βœ“ address β‰  requestβœ—
+ inode checksum / write-verifyβœ“βœ“βœ“βœ“ inode’s checksum β‰  stale data
Dotted-underlined cells have explanations β€” click one.

Different checksums guard against different faults, and as devices evolve, new failure modes will keep appearing β€” forcing us to revisit these ideas or invent new ones. Redundancy remains the key: it powers both the detection here and the recovery that follows.

Check yourself: using checksums, misdirected & lost writes

1.On reading block D, the client finds the stored checksum Cs(D) and the freshly computed checksum Cc(D) do not match. What does that mean, and what can be done?

2.Why does a basic checksum fail to catch a misdirected write, and what extra information catches it?

3.A lost write occurs: the device acknowledges a write it never persisted, so the OLD block contents remain. Why do a basic checksum and a physical ID BOTH fail to detect it, and what does?

4.Why do storage systems perform disk scrubbing rather than relying only on checks at access time?

5.Checksumming's space overhead is tiny (~0.19%), but time overhead can be noticeable. What common trick reduces the CPU cost?

6.Thinking of the cumulative defenses, which single fault is caught ONLY once you add a checksum stored away from the data (e.g. in the inode) or do a write-verify?

6 questions