linux-sysprog · intermediate · ~15 min
Memorize the canonical atomic-write recipe.
Write out the canonical step order for a crash-safe atomic file update. This is a pure-logic exercise — you fill an array with the step codes in the correct sequence; nothing is written to disk.
Implement int atomic_write_steps(int *out, int max) that writes the atomic-write step codes, in order, into out.
out, max: destination array and its capacity. The step codes are these fixed constants:enum {
STEP_WRITE_TMP = 1, // write the new content to a temp file alongside the target
STEP_FSYNC = 2, // fsync the temp file's contents to disk
STEP_FSYNC_DIR = 3, // fsync the parent directory so the rename will persist
STEP_RENAME = 4, // atomically rename the temp file over the target
};
Fills out with the 4 codes in order (STEP_WRITE_TMP, STEP_FSYNC, STEP_FSYNC_DIR, STEP_RENAME) and returns how many it wrote (at most max). The order matters: write+fsync make the new contents durable before the rename takes effect, and the directory fsync makes the rename itself survive a crash.
atomic_write_steps(out, 8) -> 4, out = [1, 2, 3, 4]
atomic_write_steps(out, 2) -> 2, out = [1, 2] (truncated to max)
max < 4: write only the first max steps and return max.max == 0: return 0.Naïve fopen("w") + write can leave a half-written file on crash. The atomic-write pattern (write to temp, fsync, rename) is what every database, every text editor, and every config-rewriting tool actually does — and very few learners are taught it explicitly.
An output array out and its capacity max. The 4 step codes are the fixed STEP_* enum constants (1..4).
Fills out with the step codes in canonical order; returns the count written (min of 4 and max).
The sequence is exactly STEP_WRITE_TMP, STEP_FSYNC, STEP_FSYNC_DIR, STEP_RENAME. Truncate to max.
enum {
STEP_WRITE_TMP = 1, STEP_FSYNC = 2, STEP_FSYNC_DIR = 3, STEP_RENAME = 4
};
int atomic_write_steps(int *out, int max) { /* TODO */ return 0; }
Forgetting fsync of the directory (step 3). Writing the temp without fsync first (step 2). Renaming first then fsync (race window — leaves the file with old content visible).
max < 4 — truncate. max == 0 — return 0.
O(1).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.