]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
iohelper: use saferead if later write with O_DIRECT
authorNikolay Shirokovskiy <nshirokovskiy@virtuozzo.com>
Thu, 28 Sep 2017 07:06:47 +0000 (10:06 +0300)
committerJiri Denemark <jdenemar@redhat.com>
Tue, 24 Oct 2017 08:53:18 +0000 (10:53 +0200)
One of the usecases of iohelper is to read from pipe and write
to file with O_DIRECT. As we read from pipe we can have partial
read and then we fail to write this data because output file
is open with O_DIRECT and buffer size is not aligned.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
src/util/iohelper.c

index 5416d4506681d82a5541768379bb5bb1901a66e8..bb8a8dde694acb2beadd5f37a31f675607da87c0 100644 (file)
@@ -109,9 +109,21 @@ runIO(const char *path, int fd, int oflags)
     while (1) {
         ssize_t got;
 
-        if ((got = read(fdin, buf, buflen)) < 0) {
-            if (errno == EINTR)
+        /* If we read with O_DIRECT from file we can't use saferead as
+         * it can lead to unaligned read after reading last bytes.
+         * If we write with O_DIRECT use should use saferead so that
+         * writes will be aligned.
+         * In other cases using saferead reduces number of syscalls.
+         */
+        if (fdin == fd && direct) {
+            if ((got = read(fdin, buf, buflen)) < 0 &&
+                errno == EINTR)
                 continue;
+        } else {
+            got = saferead(fdin, buf, buflen);
+        }
+
+        if (got < 0) {
             virReportSystemError(errno, _("Unable to read %s"), fdinname);
             goto cleanup;
         }