code wiki / (root) / nx_atomic_rewrite.nx

nx_atomic_rewrite.nx

buildroot/runtime/nx_atomic_rewrite.nx

8772 B213 linesdepth 2pulls 2 transitivereach 59 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 · 23 importers

nx_syscalls.nx nx_atomic_rewrite.nx _atomic_rewrite_gate.nx nx_aimode_read.nx nx_aimode_read_gate.nx nx_bundle_ingest.nx nx_bundle_ingest_cli_candidate_t14 nx_cast_scene_light_gate_t364.nx nx_fieldfit_lib.nx nx_fieldfit_verified_r3_t333.nx nx_fieldfit_verified_r4_t333.nx nx_gltf_clip_pack_t321.nx

diagram shows first 10 each side; +0 more imports, +13 more importers in the complete lists below.

imports: nx_syscalls.nx

imported by: _atomic_rewrite_gate.nxnx_aimode_read.nxnx_aimode_read_gate.nxnx_bundle_ingest.nxnx_bundle_ingest_cli_candidate_t144.nxnx_cast_scene_light_gate_t364.nxnx_fieldfit_lib.nxnx_fieldfit_verified_r3_t333.nxnx_fieldfit_verified_r4_t333.nxnx_gltf_clip_pack_t321.nxnx_gltf_export.nxnx_gltf_export_material_candidate_t340.nxnx_gltf_export_multipart_candidate_t345.nxnx_gltf_fullclip_bounds_gate_t321.nxnx_gltf_fullclip_pose_gate_t321.nxnx_gltf_skin_bounds_pack_t321.nxnx_gltf_skin_geometry_pack_t321.nxnx_ioconfirm_checked_test_20260907.nxnx_ioconfirm_integration_gate.nxnx_mesh2glb_neutral_candidate_t346.nxnx_profile_fit_output_t320.nxnx_profile_region_map_candidate_t366.nxnx_scene_light_recipe_canonical_gate_t364.nx

structs

none

consts

26const K_MAGIC_1024: i64 = 1024
146const AR_CHECK_OPEN: i64 = 0 - 1
147const AR_CHECK_WRITE: i64 = 0 - 2
148const AR_CHECK_RENAME: i64 = 0 - 3
149const AR_CHECK_SYNC: i64 = 0 - 4
150const AR_CHECK_CLOSE: i64 = 0 - 5
151const AR_CHECK_VERIFY: i64 = 0 - 6
152const AR_CHECK_UNCERTAIN: i64 = 0 - 7
153const AR_CHECK_EMPTY: i64 = 0 - 8
154const AR_TMP_SUFFIX_BYTES: i64 = 6
155const AR_NUL_BYTES: i64 = 1
156const AR_PTR_BYTES: i64 = 8

functions

29func ar_len(s: *u8) -> i64
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
157func ar_same_file(path: *u8, bytes: *u8, n: i64) -> i64
169func ar_syncdir_checked(path: *u8) -> i64
189func atomic_rewrite_checked(path: *u8, bytes: *u8, n: i64) -> i64