On Thu, 05/01 16:54, Stefan Hajnoczi wrote: > @@ -152,51 +132,53 @@ static void do_get_id_cmd(VirtIOBlockDataPlane *s, > complete_request_early(s, elem, inhdr, VIRTIO_BLK_S_OK); > } > > -static int do_rdwr_cmd(VirtIOBlockDataPlane *s, bool read, > - struct iovec *iov, unsigned iov_cnt, > - long long offset, VirtQueueElement *elem, > - QEMUIOVector *inhdr) > +static void do_rdwr_cmd(VirtIOBlockDataPlane *s, bool read, > + struct iovec *iov, unsigned iov_cnt, > + int64_t sector_num, VirtQueueElement *elem, > + QEMUIOVector *inhdr) > { > - struct iocb *iocb; > - QEMUIOVector qiov; > - struct iovec *bounce_iov = NULL; > - QEMUIOVector *read_qiov = NULL; > - > - qemu_iovec_init_external(&qiov, iov, iov_cnt); > - if (!bdrv_qiov_is_aligned(s->blk->conf.bs, &qiov)) { > - void *bounce_buffer = qemu_blockalign(s->blk->conf.bs, qiov.size); > - > - if (read) { > - /* Need to copy back from bounce buffer on completion */ > - read_qiov = g_slice_new(QEMUIOVector); > - qemu_iovec_init(read_qiov, iov_cnt); > - qemu_iovec_concat_iov(read_qiov, iov, iov_cnt, 0, qiov.size); > - } else { > - qemu_iovec_to_buf(&qiov, 0, bounce_buffer, qiov.size); > + VirtIOBlockRequest *req = g_slice_new(VirtIOBlockRequest);
Could be g_slice_new0, > + QEMUIOVector *qiov; > + int nb_sectors; > + > + /* Fill in virtio block metadata needed for completion */ > + memset(req, 0, sizeof(*req)); so this memset is not needed. > + req->s = s; > + req->elem = elem; > + req->inhdr = inhdr; > + req->read = read; > + qemu_iovec_init_external(&req->qiov, iov, iov_cnt); > + > + qiov = &req->qiov; > + > + if (!bdrv_qiov_is_aligned(s->blk->conf.bs, qiov)) { > + void *bounce_buffer = qemu_blockalign(s->blk->conf.bs, qiov->size); > + > + /* Populate bounce buffer with data for writes */ > + if (!read) { > + qemu_iovec_to_buf(qiov, 0, bounce_buffer, qiov->size); > } > Fam