@@ -293,6 +293,29 @@ static inline void coroutine_fn
mirror_co_wait_for_any_operation(s, false);
}
+/* Allocate a QEMUIOVector from the mirror buffer pool (s->buf_free) */
+static void coroutine_fn mirror_co_alloc_qiov(MirrorBlockJob *s,
+ QEMUIOVector *qiov,
+ int64_t offset, uint64_t bytes)
+{
+ int nb_chunks = DIV_ROUND_UP(bytes, s->granularity);
+
+ while (s->buf_free_count < nb_chunks) {
+ trace_mirror_yield_in_flight(s, offset, s->in_flight);
+ mirror_co_wait_for_free_in_flight_slot(s);
+ }
+
+ qemu_iovec_init(qiov, nb_chunks);
+ while (nb_chunks-- > 0) {
+ MirrorBuffer *buf = QSIMPLEQ_FIRST(&s->buf_free);
+ size_t remaining = bytes - qiov->size;
+
+ QSIMPLEQ_REMOVE_HEAD(&s->buf_free, next);
+ s->buf_free_count--;
+ qemu_iovec_add(qiov, buf, MIN(s->granularity, remaining));
+ }
+}
+
/*
* Restrict *bytes to how much we can actually handle, and align the
* [*offset, *bytes] range to clusters if COW is needed.
@@ -327,28 +350,9 @@ static void coroutine_fn mirror_co_read(void *opaque)
{
MirrorOp *op = opaque;
MirrorBlockJob *s = op->s;
- int nb_chunks;
uint64_t ret;
- nb_chunks = DIV_ROUND_UP(op->bytes, s->granularity);
-
- while (s->buf_free_count < nb_chunks) {
- trace_mirror_yield_in_flight(s, op->offset, s->in_flight);
- mirror_co_wait_for_free_in_flight_slot(s);
- }
-
- /* Now make a QEMUIOVector taking enough granularity-sized chunks
- * from s->buf_free.
- */
- qemu_iovec_init(&op->qiov, nb_chunks);
- while (nb_chunks-- > 0) {
- MirrorBuffer *buf = QSIMPLEQ_FIRST(&s->buf_free);
- size_t remaining = op->bytes - op->qiov.size;
-
- QSIMPLEQ_REMOVE_HEAD(&s->buf_free, next);
- s->buf_free_count--;
- qemu_iovec_add(&op->qiov, buf, MIN(s->granularity, remaining));
- }
+ mirror_co_alloc_qiov(s, &op->qiov, op->offset, op->bytes);
/* Copy the dirty cluster. */
s->in_flight++;
By pulling this function out of mirror_co_read(), the latter becomes simpler. This is important so the following patches can make it more complicated again. Signed-off-by: Max Reitz <mreitz@redhat.com> --- block/mirror.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-)