code wiki / (root) / nx_atomic_rewrite.nx

nx_atomic_rewrite.nx

buildroot/runtime/nx_atomic_rewrite.nx

6031 B141 linesdepth 2pulls 2 transitivereach 1 importersview sourcekind librarytopic atomic
docsdependenciesstructsconstsfunctions

about

nx_atomic_rewrite.nx -- WMS-R3: a GENERIC, callable atomic whole-file rewrite primitive. The reusable twin of the seg-store commit idiom (ss_writefile + sys_renameat + ss_syncdir), lifted out of the segment/manifest model into a plain (path, bytes, n) API so ANY whole-file rewriter (e.g. nx_reconcile's assignment_queue.tsv rewrite, capability ladders, status snapshots) can stop truncating-in-place. ROOT CAUSE this closes: an in-place rewrite opens O_WRONLY|O_CREAT|O_TRUNC (0x241), which TRUNCATES the live file to 0 BEFORE the new bytes land, then streams a write-loop. A crash anywhere in that loop leaves the live file truncated/torn. O_APPEND atomicity does NOT help -- it only makes ONE write() atomic, never a truncate-then-rewrite sequence. THE FIX (atomic_rewrite): stage the FULL new contents into a SIBLING temp file (same directory => same filesystem => renameat(2) is atomic), fsync the temp so its bytes are durable, then renameat(tmp -> path) -- the single atomic COMMIT POINT (a concurrent reader sees the whole old file or the whole new file, never a torn read), then fsync the parent directory so the rename itself survives power loss. A crash BEFORE the rename leaves the live file completely untouched (only the temp is partial, and the temp is never read). REUSE: idiom lifted verbatim from nx_seg_store.nx ss_writefile (write-loop + sys_fsync), ss_syncdir (dir fsync), and the temp->rename commit discipline. SOVEREIGN: nx_syscalls only; no gcc / 3rd-party. license_tier: ORIGINAL

dependencies 1 imports · 1 importers

nx_syscalls.nx nx_atomic_rewrite.nx _atomic_rewrite_gate.nx

imports: nx_syscalls.nx

imported by: _atomic_rewrite_gate.nx

structs

none

consts

26const K_MAGIC_1024: i64 = 1024

functions

29func ar_len(s: *u8) -> i64
called by 2: g_eqmain
41func ar_tmpname(path: *u8, out: *u8) -> i64
54func ar_syncdir(path: *u8) -> i64
83func atomic_rewrite(path: *u8, bytes: *u8, n: i64) -> i64
107func ar_crashwrite(path: *u8, bytes: *u8, n: i64) -> i64
130func ar_unsafe_inplace(path: *u8, bytes: *u8, n: i64) -> i64