summaryrefslogtreecommitdiff
path: root/block/raw-posix.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/raw-posix.c')
-rw-r--r--block/raw-posix.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 5c745b9a18..d737f3a0c5 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -747,6 +747,15 @@ static ssize_t handle_aiocb_rw_linear(RawPosixAIOData *aiocb, char *buf)
}
if (len == -1 && errno == EINTR) {
continue;
+ } else if (len == -1 && errno == EINVAL &&
+ (aiocb->bs->open_flags & BDRV_O_NOCACHE) &&
+ !(aiocb->aio_type & QEMU_AIO_WRITE) &&
+ offset > 0) {
+ /* O_DIRECT pread() may fail with EINVAL when offset is unaligned
+ * after a short read. Assume that O_DIRECT short reads only occur
+ * at EOF. Therefore this is a short read, not an I/O error.
+ */
+ break;
} else if (len == -1) {
offset = -errno;
break;