@@ -95,7 +95,6 @@ struct MirrorOp {
MirrorBlockJob *s;
MirrorMethod mirror_method;
- QEMUIOVector qiov;
int64_t offset;
int64_t bytes;
@@ -155,7 +154,8 @@ static void coroutine_fn mirror_wait_on_conflicts(MirrorOp *self,
}
}
-static void coroutine_fn mirror_iteration_done(MirrorOp *op, int ret)
+static void coroutine_fn mirror_iteration_done(MirrorOp *op, int ret,
+ QEMUIOVector *qiov)
{
MirrorBlockJob *s = op->s;
struct iovec *iov;
@@ -166,11 +166,13 @@ static void coroutine_fn mirror_iteration_done(MirrorOp *op, int ret)
s->in_flight--;
s->bytes_in_flight -= op->bytes;
- iov = op->qiov.iov;
- for (i = 0; i < op->qiov.niov; i++) {
- MirrorBuffer *buf = (MirrorBuffer *) iov[i].iov_base;
- QSIMPLEQ_INSERT_TAIL(&s->buf_free, buf, next);
- s->buf_free_count++;
+ if (qiov) {
+ iov = qiov->iov;
+ for (i = 0; i < qiov->niov; i++) {
+ MirrorBuffer *buf = (MirrorBuffer *) iov[i].iov_base;
+ QSIMPLEQ_INSERT_TAIL(&s->buf_free, buf, next);
+ s->buf_free_count++;
+ }
}
chunk_num = op->offset / s->granularity;
@@ -186,13 +188,16 @@ static void coroutine_fn mirror_iteration_done(MirrorOp *op, int ret)
job_progress_update(&s->common.job, op->bytes);
}
}
- qemu_iovec_destroy(&op->qiov);
+ if (qiov) {
+ qemu_iovec_destroy(qiov);
+ }
qemu_co_queue_restart_all(&op->waiting_requests);
g_free(op);
}
-static void coroutine_fn mirror_write_complete(MirrorOp *op, int ret)
+static void coroutine_fn mirror_write_complete(MirrorOp *op, int ret,
+ QEMUIOVector *qiov)
{
MirrorBlockJob *s = op->s;
@@ -205,10 +210,11 @@ static void coroutine_fn mirror_write_complete(MirrorOp *op, int ret)
s->ret = ret;
}
}
- mirror_iteration_done(op, ret);
+ mirror_iteration_done(op, ret, qiov);
}
-static void coroutine_fn mirror_read_complete(MirrorOp *op, int ret)
+static void coroutine_fn mirror_read_complete(MirrorOp *op, int ret,
+ QEMUIOVector *qiov)
{
MirrorBlockJob *s = op->s;
@@ -221,11 +227,11 @@ static void coroutine_fn mirror_read_complete(MirrorOp *op, int ret)
s->ret = ret;
}
- mirror_iteration_done(op, ret);
+ mirror_iteration_done(op, ret, qiov);
} else {
ret = blk_co_pwritev(s->target, op->offset,
- op->qiov.size, &op->qiov, 0);
- mirror_write_complete(op, ret);
+ qiov->size, qiov, 0);
+ mirror_write_complete(op, ret, qiov);
}
}
@@ -350,9 +356,10 @@ static void coroutine_fn mirror_co_read(void *opaque)
{
MirrorOp *op = opaque;
MirrorBlockJob *s = op->s;
+ QEMUIOVector qiov;
uint64_t ret;
- mirror_co_alloc_qiov(s, &op->qiov, op->offset, op->bytes);
+ mirror_co_alloc_qiov(s, &qiov, op->offset, op->bytes);
/* Copy the dirty cluster. */
s->in_flight++;
@@ -360,8 +367,8 @@ static void coroutine_fn mirror_co_read(void *opaque)
trace_mirror_one_iteration(s, op->offset, op->bytes);
ret = bdrv_co_preadv(s->mirror_top_bs->backing, op->offset, op->bytes,
- &op->qiov, 0);
- mirror_read_complete(op, ret);
+ &qiov, 0);
+ mirror_read_complete(op, ret, &qiov);
}
static int coroutine_fn mirror_co_zero(MirrorBlockJob *s,
@@ -417,7 +424,7 @@ static void coroutine_fn mirror_co_perform(void *opaque)
}
}
- mirror_iteration_done(op, ret);
+ mirror_iteration_done(op, ret, NULL);
done:
aio_context_release(aio_context);
We only need the I/O vector for data copying operations, so we do not need to put it into the MirrorOp structure and can keep it locally in mirror_co_read(). Signed-off-by: Max Reitz <mreitz@redhat.com> --- block/mirror.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-)