Problem Description: read, readv, write and writev system calls are not atomic even though standards require them to. They are not atomic because the sys_ functions in fs/read_write.c copy the value of variable f_pos to and from a local variable without locking.
The f_pos thing is a know issue, and many people things that its not a bug/the spect allows it/a program that relies on it is "broken". Other people think it should be fixed. It's a hot discussion every time someone brings it. Unless someone manages to convince the rest of the people that it should be fixed and gets a patch merged, i think you should consider it as a WILL_NOT_FIX bug.
(In reply to comment #1) > The f_pos thing is a know issue, and many people things that its not a > bug/the > spect allows it/a program that relies on it is "broken". Other people think > it > should be fixed. It's a hot discussion every time someone brings it. Unless > someone manages to convince the rest of the people that it should be fixed > and > gets a patch merged, i think you should consider it as a WILL_NOT_FIX bug. Diego, Could you point me at some discussions of this? Maybe I need to add something to the man page.
There're a lot of threads http://lkml.org/lkml/2006/4/13/2 http://lkml.org/lkml/2007/3/12/28 http://lkml.org/lkml/2007/3/7/672 http://lkml.org/lkml/2004/2/6/11 http://thread.gmane.org/gmane.linux.file-systems/20712/focus=20771 http://lkml.org/lkml/2008/4/10/132
(In reply to comment #0) > Problem Description: read, readv, write and writev system calls are not > atomic > even though standards require them to. They are not atomic because the sys_ > functions in fs/read_write.c copy the value of variable f_pos to and from a > local variable without locking. Matti, Can you describe a userspace scenario where one can demonstrate the non-atomicity? Cheers, Michael
(In reply to comment #0) > Problem Description: read, readv, write and writev system calls are not > atomic > even though standards require them to. They are not atomic because the sys_ > functions in fs/read_write.c copy the value of variable f_pos to and from a > local variable without locking. Matti, Do you mean "not atomic" or do you mean "not thread safe"?
A userspace scenario where one can demonstrate the non-atomicity would be to have several threads to read, write or seek the same file through the same file descriptor. I mean not atomic and not thread-safe.
I can easily enough demonstrate code that demonstrates "not thread-safe" but I'm having trouble triggering non-atomic. Can you say a bit more about that precise case, or do you eben have some (simple) code that demonstrates it?
Why do you have trouble triggering non-atomic? I think thread-unsafety is enough to prove non-atomicity.
(In reply to comment #8) > Why do you have trouble triggering non-atomic? I think thread-unsafety is > enough to prove non-atomicity. Perhaps I'm getting too hung up on a particular case. If we do a vectored write (writev()), I'm expecting that the non-atomicity might mean that output bu other threads may be interspersed with the output of our writev(). Is that a possibility? If yes, I'm puzzled that I can' reproduce it.
If we do a write or writev, I'm expecting that the non-atomicity might mean that output by other threads may be interspersed with the output of our writing. That is a possibility. You need to time the threads so that they run simultaneously. At least two threads must read f_pos before the other one writes to it.
The only case where you are guaranteed specific behaviour I can find in the standard is that O_APPEND always appends and that is handled by the kernel very carefully. POSIX added pread/pwrite interfaces for a very good reason...
The Open Group Base Specifications Issue 6 IEEE Std 1003.1, 2004 Edition: "I/O is intended to be atomic to ordinary files and pipes and FIFOs. Atomic means that all the bytes from a single operation that started out together end up together, without interleaving from other I/O operations." http://www.opengroup.org/onlinepubs/000095399/functions/read.html
(In reply to comment #12) > The Open Group Base Specifications Issue 6 > IEEE Std 1003.1, 2004 Edition: > "I/O is intended to be atomic to ordinary files and pipes and FIFOs. Atomic > means that all the bytes from a single operation that started out together > end > up together, without interleaving from other I/O operations." > http://www.opengroup.org/onlinepubs/000095399/functions/read.html Matti's point seems on the mark to me. Seems reasonable to reopen this bug.
That is why a local variable copy is used - so that if ppos is shifted by another process mid readv/writev our I/O still completes in the right place
Linux does not guarantee that write operations to adjacent bytes are atomic. They are not atomic in the Alpha architecture.
For what it's worth, I believe this problem was fixed in Linux 3.14, by commit 9c225f2655e36a470c4f58dbbc99244c5fc7f2d4 but it would be interesting to have confirmation of that. See also http://thread.gmane.org/gmane.linux.kernel/1649458 (LKML thread: "Update of file offset on write() etc. is non-atomic with I/O"; 2014-02-17 15:41:37 GMT)