Skip to contentSkip to conversation

block: prevent multiwrite_merge from creating too large iovecs

PATCH Applied Christoph Hellwig 3 participants 8 messages Jan 19, 2010 – Jan 26, 2010

v1 of 2 Applied Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 block: prevent multiwrite_merge from creating too large iovecs

If we go over the maximum number of iovecs support by syscall we get back EINVAL from the kernel which translate to I/O errors for the guest.

block.c +4 -0
Index: qemu/block.c
===================================================================
@@ -1711,6 +1711,10 @@ static int multiwrite_merge(BlockDriverS
             merge = bs->drv->bdrv_merge_requests(bs, &reqs[outidx], &reqs[i]);
         }
 
+        if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1 > IOV_MAX) {
+            merge = 0;
+        }
+
         if (merge) {
             size_t size;
             QEMUIOVector *qiov = qemu_mallocz(sizeof(*qiov));
#1 lore raw

Am 19.01.2010 22:15, schrieb Christoph Hellwig:

Quoted 4 lines

If we go over the maximum number of iovecs support by syscall we get back EINVAL from the kernel which translate to I/O errors for the guest.

Is this really enough? We don't check for IOV_MAX in any other place, so can't we get a too big request directly from virtio-blk?

What about handling it transparently in qemu_pwritev/preadv and laio_submit? Logically, it's a limitation of the backend anyway and not a generic restriction.

To underline that it's a backend/platform dependent thing: Your patch breaks the mingw build for me.

Kevin

#2 lore raw
Quoted 8 lines · Kevin Wolf

Am 19.01.2010 22:15, schrieb Christoph Hellwig:

Quoted 4 lines

If we go over the maximum number of iovecs support by syscall we get back EINVAL from the kernel which translate to I/O errors for the guest.

Is this really enough? We don't check for IOV_MAX in any other place, so can't we get a too big request directly from virtio-blk?

Currently the virtqueue is limited to 1024 iovecs, but I plan to put in some better infrastructure to deal with the queue limit. For now this patch fixes an issue that we see with real life setups.

#3 lore raw

Am 20.01.2010 17:24, schrieb Christoph Hellwig:

Quoted 5 lines · Kevin Wolf
Quoted 4 lines

Am 19.01.2010 22:15, schrieb Christoph Hellwig:

Quoted 3 lines

If we go over the maximum number of iovecs support by syscall we get back EINVAL from the kernel which translate to I/O errors for the guest.

Quoted 8 lines
Quoted 4 lines
Quoted 1 line

Is this really enough? We don't check for IOV_MAX in any other place, so can't we get a too big request directly from virtio-blk?

Currently the virtqueue is limited to 1024 iovecs, but I plan to put in some better infrastructure to deal with the queue limit. For now this patch fixes an issue that we see with real life setups.

Ok, if you're planning to replace it by something real, I'm not opposed to using this as a quick fix for the meantime. However, it needs an #ifdef for the mingw build breakage at least.

Kevin

#4 lore raw
In reply to Kevin Wolf
Quoted 2 lines · Kevin Wolf

To underline that it's a backend/platform dependent thing: Your patch breaks the mingw build for me.

Actually that's because mingw is the usual piece of crap and doesn't actually have any of the vector support you can expect from a normal Unix system.

I can either throw in an #ifdef IOV_MAX around the check or fake one up for mingw. Does any of the maintainers have a preference for either variant?

#5 lore raw
Quoted 5 lines · Christoph Hellwig
Quoted 3 lines · Kevin Wolf

To underline that it's a backend/platform dependent thing: Your patch breaks the mingw build for me.

Quoted 8 lines

Actually that's because mingw is the usual piece of crap and doesn't actually have any of the vector support you can expect from a normal Unix system.

I can either throw in an #ifdef IOV_MAX around the check or fake one up for mingw. Does any of the maintainers have a preference for either variant?

grep for CONFIG_IOVEC in qemu-common.h and add a #define IOV_MAX.

mingw doesn't have iovec so we introduce a compat version.

Regards,

Anthony Liguori

#6 lore raw
Quoted 8 lines · Anthony Liguori
Quoted 4 lines

I can either throw in an #ifdef IOV_MAX around the check or fake one up for mingw. Does any of the maintainers have a preference for either variant?

grep for CONFIG_IOVEC in qemu-common.h and add a #define IOV_MAX.

mingw doesn't have iovec so we introduce a compat version.

Yes, that's what I meant with the second alternative above.

#7 lore raw
In reply to Christoph Hellwig
Quoted 5 lines · Christoph Hellwig

If we go over the maximum number of iovecs support by syscall we get back EINVAL from the kernel which translate to I/O errors for the guest.

Applied. Thanks.

Regards,

Anthony Liguori

Quoted 19 lines

Index: qemu/block.c
===================================================================

block.c +4 -0
@@ -1711,6 +1711,10 @@ static int multiwrite_merge(BlockDriverS
              merge = bs->drv->bdrv_merge_requests(bs,&reqs[outidx],&reqs[i]);
          }
 
+        if (reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1>  IOV_MAX) {
+            merge = 0;
+        }
+
          if (merge) {
              size_t size;
              QEMUIOVector *qiov = qemu_mallocz(sizeof(*qiov));