1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//! The single directory-entry fsync primitive (FENCE-CHAIN r8 R1a).
//!
//! Every directory-entry fsync the fence-chain brief introduces or touches funnels
//! through [`sync_dir_entry`]. Consolidating them in one helper gives the crash
//! battery a single seam to instrument: the FAILPOINT hook (drive the post-mutation
//! refusal tail no real filesystem produces on demand), the LOSSY hook (suppress the
//! real fsync so a still-pending directory-entry mutation survives to the CUT), and
//! the OBSERVER hook (count real syncs by normalised path, so fsync-neutrality on a
//! warm commit is a runnable assertion — R4b).
//!
//! The primitive itself is tiny and production-only: open the directory read-only and
//! `sync_all` it so a rename's directory entry — not just the renamed file's
//! contents — survives power loss. It is Unix-only for the same reason as the
//! pre-existing per-subsystem helpers it supersedes: `std` cannot open a directory
//! for fsync on Windows (`FILE_FLAG_BACKUP_SEMANTICS` is required and unset), so
//! there the directory-entry sync is skipped — a documented platform gap carried as
//! a row in the R2 audit table.
use io;
use Path;
/// fsync the directory entry at `parent`, making a just-renamed or just-created
/// entry inside it durable.
///
/// On success the fence-chain journal (test builds only) clears exactly the
/// directory-entry mutations that were pending against `parent` when the sync
/// began; a mutation registered mid-sync stays pending, so a fence can never
/// falsely certify an entry it did not cover.
/// Non-Unix platforms cannot open a directory for fsync through `std`; the
/// directory-entry sync is skipped there (documented R2 gap). The FAILPOINT hook
/// is still honoured so the crash battery's refusal walls compile and run.
/// Lexically normalise a parent path so the OBSERVER counts and the journal's
/// per-parent pending sets key identically whether a caller passed an absolute
/// path, a relative one, or `""` (mapped to `.`). Never touches the filesystem —
/// the target may already be gone by the time a CUT normalises it.
pub