Date: Tue, 15 Jun 2021 14:49:57 -0400 From: Kurt Hackenberg <kh@panix.com> To: freebsd-questions@freebsd.org Subject: Re: Is a successful call to write(2) atomic? Message-ID: <44e15917-0c92-08f2-462e-a1b3705f9afb@panix.com> In-Reply-To: <22440.1623740785@segfault.tristatelogic.com> References: <22440.1623740785@segfault.tristatelogic.com>
next in thread | previous in thread | raw e-mail | index | archive | help
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. 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.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?44e15917-0c92-08f2-462e-a1b3705f9afb>