Let's assume we opened a file using fopen()
and from the file-pointer received, fetch the file-descriptor using fileno()
. Then we do lots (>10^8) of random read()
s of relativly small chunks, between a size of 4Bytes to 10KBytes from this file:
Is it expected behaviour such a read()
might return less bytes then requested, without setting errno
, if the file-system is an
ext3
NFS
OCFS2
combination of 2 and 3 (
OCFS2
viaNFS
)
?
My readings gave me the conclusion it should not be possible for 1. (if the file has not O_NONBLOCK
set, if ever possible for ext3
to have it set) but for the other three (2., 3., 4.) I'm uncertain.
(Btw: Could I assume having O_NONBLOCK
not set to be the default in any case?)
This questions arose because I observed read()
s returning less bytes then requested without errno
set in case 4.
The problem to drill this down by testing is that such behaviour happens in <1/1000000000 cases ... - which is still too often :-}
Update: The average file size is between some TBytes and around 1GByte.
You should not assume that read() will not return less bytes than requested for any filesystem. This is particularly true in the case of large reads, as POSIX.1 indicates that read() behavior for sizes larger than SSIZE_MAX is implementation-dependent. On this mainstream Unix box I'm using right now, SSIZE_MAX is 32767 bytes. The fact that read() always returns the full amount today does not mean that it will in the future.
One possible reason might be that I/O priorities are more fully fleshed out in the kernel in the future. E.g. you're trying to read from the same device as another higher priority process and the other process would get better throughput if your process wasn't causing head movement away from the sectors the other process wants. The kernel might choose to give your read() a short count to get you out of the way for a while, instead of continuing to do inefficient interleaved block reads. Stranger things have been done for the sake of I/O efficiency. What is not prohibited often becomes compulsory.