提交 633b699b 编写于 作者: D Daniel P. Berrange

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: NNikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
Reviewed-by: NEric Blake <eblake@redhat.com>
Signed-off-by: NDaniel P. Berrange <berrange@redhat.com>
上级 eae746b2
...@@ -109,7 +109,9 @@ runIO(const char *path, int fd, int oflags) ...@@ -109,7 +109,9 @@ runIO(const char *path, int fd, int oflags)
while (1) { while (1) {
ssize_t got; ssize_t got;
if ((got = saferead(fdin, buf, buflen)) < 0) { if ((got = read(fdin, buf, buflen)) < 0) {
if (errno == EINTR)
continue;
virReportSystemError(errno, _("Unable to read %s"), fdinname); virReportSystemError(errno, _("Unable to read %s"), fdinname);
goto cleanup; goto cleanup;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册