Is a successful call to write(2) atomic?

Kurt Hackenberg kh at
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 
intended to.

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 
idea now.

More information about the freebsd-questions mailing list