Is a successful call to write(2) atomic?

Michael Schuster michaelsprivate at gmail.com
Tue Jun 15 19:16:14 UTC 2021


On Tue, Jun 15, 2021 at 8:50 PM Kurt Hackenberg <kh at panix.com> wrote:

> 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
> processes.
>
> 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.
>

I think what you're describing - synchronous or not - is orthogonal to what
Ronald is asking.
Let's take a step back: an atomic write() either writes everything or
nothing - and that's all. There's nothing in that claim that says
"everything must be in a contiguous block", nor, that all the data must be
written in a single "operation" by the underlying system.

So after consideration I don't think the observed behaviour is violating
the claim that write() is atomic - I welcome correction, of course :-)

regards
Michael

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.
> _______________________________________________
> freebsd-questions at freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-questions
> To unsubscribe, send any mail to "
> freebsd-questions-unsubscribe at freebsd.org"
>


-- 
Michael Schuster
http://recursiveramblings.wordpress.com/
recursion, n: see 'recursion'


More information about the freebsd-questions mailing list