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