Persist the file, then persist the name that publishes it
Derive a Linux local-filesystem replacement protocol using checked writes, file synchronization, rename, and directory synchronization.
On this page
The question for today
What you’ll understand
- Separate atomic name replacement from crash durability of the replacement.
- Order file and containing-directory synchronization in a publication protocol.
- Classify failed synchronization as an uncertain outcome rather than a durable acknowledgment.
A checkpoint publisher wants readers to find either the old complete generation or the new complete generation, and wants an acknowledgment to mean the new generation survives the stated crash model. These are two related promises: atomic visibility and durable publication. On Linux local filesystems, they require reasoning about both the file's contents and the directory entry that makes those contents reachable. This lesson derives a protocol under explicit assumptions rather than treating rename or close as a universal commit operation.
Persisting contents does not necessarily persist a new name
A successful fsync on a regular file requests persistence of its modified contents and associated file metadata through the documented storage boundary. Linux's interface explicitly distinguishes this from making the containing directory entry durable: that requires synchronization of the directory. The distinction matters most when a file was created, removed, or renamed. A durable inode and payload that cannot be reached by the expected post-crash name may fail the application's contract even though the bytes existed somewhere in the filesystem's recovery state.
Language-level flush normally drains a user-space buffer to the operating system; it does not replace fsync. The related fdatasync interface can omit metadata changes unnecessary for correct later data retrieval, but required size changes still matter. Check every write's byte count and every synchronization result. If persistence fails, the publisher must not report durable success just because earlier writes returned. An error can leave an uncertain mixture of progressed operations, so the recovery design should inspect generation identities and verified contents instead of assuming an error means nothing happened.
Derive a narrow replacement protocol
Assume a trusted, already durable parent directory on one supported local filesystem, a single coordinated publisher, and storage that honors the required persistence operations. Create a uniquely named temporary file in that same directory without accidentally opening an existing object. Write the full generation, set required attributes at the appropriate point, and fsync the temporary file successfully. Rename it over the public name, then fsync the parent directory successfully before acknowledging durable publication. The same-directory assumption keeps the naming update inside one directory and avoids cross-filesystem rename semantics.
Same-filesystem rename can provide atomic replacement of the destination name for concurrent lookups, but already open descriptors can continue reading the old inode. It does not atomically switch a reader's independently opened collection of several files. For a multi-file checkpoint, immutable generation directories or files plus a verified manifest can reduce the public switch to one reference, but the contents, hierarchy, and publication protocol still need their own persistence ordering. Cross-directory moves require reasoning about both changed directories, and network filesystems or unsupported directory fsync require their documented contracts rather than copying this local example blindly.
Recover from interruption instead of assuming a clean return
A crash before acknowledgment may leave an old public generation, a new one, or temporary debris within the filesystem's allowed persistence behavior. Recovery should validate the public generation's manifest and digest, use documented committed-state rules, and clean temporary artifacts only after determining which files are still referenced. The protocol's durable acknowledgment is the strong boundary; an interrupted earlier call does not promise a particular result. If an error follows rename, do not casually roll back by deleting the public name, because the rename may already be visible and could have become durable.
The queue lab illustrates acknowledgment pressure rather than executing this protocol. Interpret equal-sized publication jobs arriving at λ and completing their entire required durable sequence at μ. Press Reset, set both arrival to four and durable service to two, predict growth from the initial four jobs, then Play or Step. Before any comparison, Reset again and re-enter both desired rates: edits retain elapsed time and recalculate from four, rather than changing a live accumulated queue. Reducing synchronization steps in the real protocol would change its semantics. The animation has no files, directory descriptors, or syscall errors; test the ordered publication steps separately on disposable storage.
Work it through
Locate the acknowledgment boundary in time
A serialized publisher writes a complete 12 MB generation in 20 ms, successfully fsyncs the file in 7 ms, renames it in 1 ms, and successfully fsyncs its existing parent directory in 4 ms. Ignore other overhead.
After 20 ms, writes have completed but the protocol has not yet established its required durable file boundary. At 27 ms the successful file fsync supplies that boundary.
Rename finishes at 28 ms, making the replacement name visible under the stated local semantics. That return alone does not establish persistence of the directory update.
The successful parent-directory fsync finishes at 32 ms. Only then does this protocol acknowledge durable publication. A crash at 29 ms is before acknowledgment and requires recovery to accept the allowed old-or-new result.
Durable acknowledgment occurs at 32 ms in this illustrative trace. The one-millisecond rename cost is neither the whole commit latency nor evidence that its name change survives a crash.
The living notebook
Explore the model
Interactive lab · queue
Queue complete durable publications
Reset, set both λ=4 and μ=2 for equal-sized publication jobs, predict growth from four, then Play or Step. Reset and re-enter both desired rates before a separate comparison; edits retain elapsed time and recalculate from the initial four. This fluid model does not execute fsync or rename, and faster service cannot justify dropping a persistence step.
- Fluid backlog
- 4
- Net rate · λ − μ
- −1 /s
- M/M/1 mean residence
- 1 s
Fluid backlog starts at 4 and follows max(0, 4 + (λ − μ)t). The separate M/M/1 residence-time formula assumes Poisson arrivals, exponential service and λ < μ. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forManage admission and batching around a durability contract instead of redefining completion to make a queue look faster.
Pause & reason
Check your understanding
Your turn
Try it yourself
A publisher completes file fsync and rename, but directory fsync returns an I/O error. Should it acknowledge durable success, and why is deleting the public name immediately an unsafe generic recovery policy?
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Separate what may already be visible from what has been proven durable.
Compare with the solution
It must not acknowledge the promised durable success because the required directory boundary failed. The rename may already be visible and may even have reached storage, so deleting the public name can destroy an otherwise usable generation or confuse readers. Report the failure and recover by validating generation identities and contents under a documented protocol rather than assuming no change occurred.
Keep the idea
Take it with you
- Atomic name replacement and durable name replacement are distinct promises.
- A local same-directory publication protocol synchronizes contents before rename and directory state afterward.
- Persistence errors require explicit uncertain-outcome recovery and must not be converted into durable success.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.