Make alignment of last direct write more straightforward. Using additionally two flags 'end' and 'shortRead' looks complicated. --- src/util/iohelper.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/util/iohelper.c b/src/util/iohelper.c index 5fc311b..1896fd3 100644 --- a/src/util/iohelper.c +++ b/src/util/iohelper.c @@ -55,7 +55,6 @@ runIO(const char *path, int fd, int oflags) const char *fdinname, *fdoutname; unsigned long long total = 0; bool direct = O_DIRECT && ((oflags & O_DIRECT) != 0); - bool shortRead = false; /* true if we hit a short read */ off_t end = 0; #if HAVE_POSIX_MEMALIGN @@ -115,30 +114,32 @@ runIO(const char *path, int fd, int oflags) goto cleanup; } if (got == 0) - break; /* End of file before end of requested data */ - if (got < buflen) { - /* O_DIRECT can handle at most one short read, at end of file */ - if (direct && shortRead) { - virReportSystemError(EINVAL, "%s", - _("Too many short reads for O_DIRECT")); - } - shortRead = true; - } + break; total += got; - if (fdout == fd && direct && shortRead) { - end = total; + + /* handle last write size align in direct case */ + if (got < buflen && direct && fdout == fd) { memset(buf + got, 0, buflen - got); got = (got + alignMask) & ~alignMask; + + if (safewrite(fdout, buf, got) < 0) { + virReportSystemError(errno, _("Unable to write %s"), fdoutname); + goto cleanup; + } + + if (ftruncate(fd, total) < 0) { + virReportSystemError(errno, _("Unable to truncate %s"), fdoutname); + goto cleanup; + } + + break; } + if (safewrite(fdout, buf, got) < 0) { virReportSystemError(errno, _("Unable to write %s"), fdoutname); goto cleanup; } - if (end && ftruncate(fd, end) < 0) { - virReportSystemError(errno, _("Unable to truncate %s"), fdoutname); - goto cleanup; - } } /* Ensure all data is written */ -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list