Bug 10596 - read, readv, write and writev system calls are not atomic
Summary: read, readv, write and writev system calls are not atomic
Status: REJECTED WILL_NOT_FIX
Alias: None
Product: File System
Classification: Unclassified
Component: Other (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: fs_other
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-05-03 00:33 UTC by Matti Linnanvuori
Modified: 2016-01-28 20:41 UTC (History)
3 users (show)

See Also:
Kernel Version: 2.6.25-git19
Tree: Mainline
Regression: No


Attachments

Description Matti Linnanvuori 2008-05-03 00:33:27 UTC
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.
Comment 1 Diego Calleja 2008-05-03 07:03:27 UTC
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.
Comment 2 Michael Kerrisk 2008-05-20 03:10:25 UTC
(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.
Comment 4 Michael Kerrisk 2008-05-20 08:47:05 UTC
(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
Comment 5 Michael Kerrisk 2008-05-20 13:15:38 UTC
(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"?
Comment 6 Matti Linnanvuori 2008-05-21 05:02:13 UTC
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.
Comment 7 Michael Kerrisk 2008-05-21 05:47:06 UTC
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?
Comment 8 Matti Linnanvuori 2008-05-21 07:50:19 UTC
Why do you have trouble triggering non-atomic? I think thread-unsafety is enough to prove non-atomicity.
Comment 9 Michael Kerrisk 2008-05-21 08:54:43 UTC
(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.
Comment 10 Matti Linnanvuori 2008-05-22 00:20:39 UTC
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.
Comment 11 Alan 2008-09-23 03:56:02 UTC
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...
Comment 12 Matti Linnanvuori 2008-09-25 03:26:08 UTC
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
Comment 13 Michael Kerrisk 2008-09-25 03:32:50 UTC
(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.
Comment 14 Alan 2008-09-25 03:33:59 UTC
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
Comment 15 Matti Linnanvuori 2008-09-25 04:08:59 UTC
Linux does not guarantee that write operations to adjacent bytes are atomic. They are not atomic in the Alpha architecture.
Comment 16 Michael Kerrisk 2016-01-28 20:41:04 UTC
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)

Note You need to log in before you can comment on or make changes to this bug.