]> git.ipfire.org Git - thirdparty/libvirt.git/commit
iohelper: avoid calling read() with misaligned buffers for O_DIRECT
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 20 Sep 2017 15:25:56 +0000 (16:25 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 21 Sep 2017 07:52:13 +0000 (08:52 +0100)
commit633b699bfda06d9fcdb7f9466e2d2c9b4bc3e63c
tree112d4cd8627344c7d5429103434925a669e15993
parenteae746b2d75973babf1d8b5095db1c7c53573659
iohelper: avoid calling read() with misaligned buffers for O_DIRECT

The iohelper currently calls saferead() to get data from the
underlying file. This has a problem with O_DIRECT when hitting
end-of-file. saferead() is asked to read 1MB, but the first
read() it does may return only a few KB, so it'll try another
read() to fill the remaining buffer. Unfortunately the buffer
pointer passed into this 2nd read() is likely not aligned
to the extent that O_DIRECT requires, so rather than seeing
'0' for end-of-file, we'll get -1 + EINVAL due to misaligned
buffer.

The way the iohelper is currently written, it already handles
getting short reads, so there is actually no need to use
saferead() at all. We can simply call read() directly. The
benefit of this is that we can now write() the data immediately
so when we go into the subsequent reads() we'll always have a
correctly aligned buffer.

Technically the file position ought to be aligned for O_DIRECT
too, but this does not appear to matter when at end-of-file.

Tested-by: Nikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
src/util/iohelper.c