What we are building
We maintain an append-only on-disk store. Every update has the same shape:
write a temporary file and make its contents durable;
rename() it to its final name;
only then publish the new state to the rest of the system.
Step 3 is the one we must get right. Once we publish, other components treat the preceding step
as committed. If power is lost after we publish but the renamed entry was not yet durable, we
would have published a state the filesystem can no longer support after reboot.
Our question is therefore narrow: after rename() returns, what does Apple document about
when the resulting directory entry may be treated as durable across power loss? Two cases
matter, and we would like them distinguished wherever the answer differs:
the target name did not exist before — an entry is added;
the target name already existed and is replaced — an entry is replaced and an older link
is removed.
We are not asking you to review or endorse our protocol — only what the platform documents.
What we have read, and where we stopped
fsync(2) here causes "all modified data and attributes of fildes to be moved to a
permanent storage device", then warns that after power loss an application "may find that
only some or none of their data was written".
fcntl(2) says of F_FULLFSYNC that "data that had been fsync'd on the same device before
is guaranteed to be persisted when this call returns", and lists APFS as supported.
rename(2) "guarantees that an instance of new will always exist, even if the system should
crash in the middle of the operation".
In what we read, we did not find a statement connecting a successful synchronisation call on
a descriptor that refers to a directory with the durability of a name added, removed or
replaced in that directory. We are not claiming no such statement exists — only that we did not
find one, which is why we are asking.
Three questions, independent of one another
Q1 — How are these calls supported on a directory descriptor?
On APFS, how are fsync(2) and fcntl(fd, F_FULLFSYNC) supported when fd refers to a
directory (for example one obtained with O_DIRECTORY)? Please treat the two calls separately,
since they carry different documented guarantees. "Supported", "not supported" and "not
specified for this use" are all useful answers to us.
Q2 — If such a call succeeds, what does it cover?
If the call in Q1 returns successfully, which changes are guaranteed to have been completed —
the directory's own attributes; the entries added, removed or replaced; related metadata? We are
asking for the documented scope, not the implementation.
Q3 — Is there a documented sequence an application can rely on?
Is there a sequence of calls that Apple documents for an application that needs the name
resulting from a rename() to survive power loss before it publishes its next state? If so,
we would appreciate the reference, the conditions it depends on — filesystem, device, call
ordering — and its stated limits. If there is no public commitment of this kind, we would rather
be told so plainly, together with whatever level you are able to confirm, including "this is not
currently specified" if that is the accurate answer.
One distinction we do not want to get wrong
rename(2) uses the word crash. We do not want to read a statement about crash behaviour as
one about power loss, since the two can differ at the device layer. If a documented guarantee
covers one and not the other, that distinction is exactly what we need.
We also note the device-level caveat in the same manual page — certain drives "have also been
known to ignore the request to flush their buffered data" — and we are not asking you to speak
for any particular drive.
Environment
macOS 26.3, build 25D125, APFS — read on our own development machine and reported here as such;
not independently verified by a third party.
Deliberately outside this request
A rename() between two different directories touches a source directory and a target
directory. Whether a guarantee would have to cover both is tracked separately and is not
asked here, so that an answer about one directory is not read as covering two.
We have not fixed where the temporary file lives, and we are not asking you to choose that
layout. Nor do we assume your answer is independent of it: if any of the above depends on
whether the source and target directories are the same directory or two different ones, please
say so explicitly. We would rather be told the answer is conditional than read an
unconditional answer into it.
1
0
289