Is a successful call to write(2) atomic?
kh at panix.com
Tue Jun 15 18:50:01 UTC 2021
On 2021/06/15 03:06, Ronald F. Guilmette wrote:
> This is deeply distrubing. I never knew about this. I am furiously reading
> the FreeBSD & Linux man pages for open(2). (It appears that both support
> that flags, O_DIRECT and O_SYNC, aqnd Linux also adds the O_DSYNC flag.
No, write(2) is not guaranteed atomic, and that's not obvious. Probably
a lot of people have learned that the hard way.
All I know about those flags is what I just read in the man page, but I
think they don't guarantee atomic writes either -- at least, they're not
The sync stuff means the system call won't return until the data has
been written to disk (as opposed to queuing the write to be executed
sometime later). That doesn't say anything about interleaving with other
Direct -- non-cached -- sounds like sort of the same thing, but at a
different level, and it isn't even guaranteed to do that. The man page
doesn't say much.
Either of those might slow things down a lot, without necessarily
solving your problem. Either might make the problem less likely to
occur, and so harder to debug. I suggest that you don't use those flags
for this purpose.
This is an old, general problem: concurrent access to a shared resource.
There are two common solutions. Paul suggested one of them: serialize
access through a single process. The other is to serialize it through
some kind of lock, that can only be held by one process at a time. Each
process acquires the lock, uses the shared resource briefly, and
immediately releases the lock. Semaphores are that kind of lock,
invented for that purpose.
Unix file systems have file locking, which does that for all or part of
a file; see fcntl(2). Note that Unix file locking is advisory --
voluntary -- not compulsory. It only works if all the processes agree to
use it. Also, in the past, it has not always worked for files accessed
across the network, through NFS. I don't know whether it works through
modern NFS. It's best to use it only for local files.
Both approaches work fine, if they're done correctly; they're both a
little complicated to implement. Getting it right requires a clear
understanding of the problem and the solution. Sounds like you have the
More information about the freebsd-questions