b85e620
From c0c1147350005b47068285a288f848cf75eb60c6 Mon Sep 17 00:00:00 2001
b85e620
From: Christoph Hellwig <hch@lst.de>
b85e620
Date: Tue, 26 Jan 2010 14:49:08 +0100
b85e620
Subject: [PATCH] block: avoid creating too large iovecs in multiwrite_merge
b85e620
b85e620
If we go over the maximum number of iovecs support by syscall we get
b85e620
back EINVAL from the kernel which translate to I/O errors for the guest.
b85e620
b85e620
Add a MAX_IOV defintion for platforms that don't have it.  For now we use
b85e620
the same 1024 define that's used on Linux and various other platforms,
b85e620
but until the windows block backend implements some kind of vectored I/O
b85e620
it doesn't matter.
b85e620
b85e620
Signed-off-by: Christoph Hellwig <hch@lst.de>
b85e620
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
b85e620
---
b85e620
 block.c       |    4 ++++
b85e620
 qemu-common.h |    4 ++++
b85e620
 2 files changed, 8 insertions(+), 0 deletions(-)
b85e620
b85e620
diff --git a/block.c b/block.c
b85e620
index 97af3f5..9697dc9 100644
b85e620
--- a/block.c
b85e620
+++ b/block.c
b85e620
@@ -1669,6 +1669,10 @@ static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
b85e620
             merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]);
b85e620
         }
b85e620
b85e620
+        if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) {
b85e620
+            merge = 0;
b85e620
+        }
b85e620
+
b85e620
         if (merge) {
b85e620
             size_t size;
b85e620
             QEMUIOVector *qiov = qemu_mallocz(sizeof(*qiov));
b85e620
diff --git a/qemu-common.h b/qemu-common.h
b85e620
index 1c5c0b2..b604ddf 100644
b85e620
--- a/qemu-common.h
b85e620
+++ b/qemu-common.h
b85e620
@@ -54,6 +54,10 @@ struct iovec {
b85e620
     void *iov_base;
b85e620
     size_t iov_len;
b85e620
 };
b85e620
+/*
b85e620
+ * Use the same value as Linux for now.
b85e620
+ */
b85e620
+#define IOV_MAX		1024
b85e620
 #else
b85e620
 #include <sys/uio.h>
b85e620
 #endif
b85e620
-- 
b85e620
1.6.6.1
b85e620