aboutsummaryrefslogtreecommitdiff
path: root/block/mirror.c
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2014-07-01 16:52:21 +0200
committerStefan Hajnoczi <stefanha@redhat.com>2014-07-07 09:15:29 +0200
commit5a0f6fd5c84573387056e0464a7fc0c6fb70b2dc (patch)
tree21b36dcf76f149c0bc3272c2a571ee0825db6647 /block/mirror.c
parentbc3a7f90ff44037bbe898708081db23a08fa7189 (diff)
mirror: Fix qiov size for short requests
When mirroring an image of a size that is not a multiple of the mirror job granularity, the last request would have the right nb_sectors argument, but a qiov that is rounded up to the next multiple of the granularity. Don't do this. This fixes a segfault that is caused by raw-posix being confused by this and allocating a buffer with request length, but operating on it with qiov length. [s/Driver/Drive/ in qemu-iotests 041 as suggested by Eric --Stefan] Reported-by: Eric Blake <eblake@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Tested-by: Eric Blake <eblake@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'block/mirror.c')
-rw-r--r--block/mirror.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/block/mirror.c b/block/mirror.c
index 6c3ee7041c..c7a655fc58 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -265,9 +265,11 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
next_sector = sector_num;
while (nb_chunks-- > 0) {
MirrorBuffer *buf = QSIMPLEQ_FIRST(&s->buf_free);
+ size_t remaining = (nb_sectors * BDRV_SECTOR_SIZE) - op->qiov.size;
+
QSIMPLEQ_REMOVE_HEAD(&s->buf_free, next);
s->buf_free_count--;
- qemu_iovec_add(&op->qiov, buf, s->granularity);
+ qemu_iovec_add(&op->qiov, buf, MIN(s->granularity, remaining));
/* Advance the HBitmapIter in parallel, so that we do not examine
* the same sector twice.