[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCHv3 4/9] consolidate qemu_iovec_copy() and qemu_io
From: |
Paolo Bonzini |
Subject: |
Re: [Qemu-devel] [PATCHv3 4/9] consolidate qemu_iovec_copy() and qemu_iovec_concat() and make them consistent |
Date: |
Tue, 13 Mar 2012 19:02:23 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:10.0.1) Gecko/20120216 Thunderbird/10.0.1 |
Il 12/03/2012 20:14, Michael Tokarev ha scritto:
> qemu_iovec_concat() is currently a wrapper for
> qemu_iovec_copy(), use the former (with extra
> "0" arg) in a few places where it is used.
>
> Change skip argument of qemu_iovec_copy() from
> uint64_t to size_t, since size of qiov itself
> is size_t, so there's no way to skip larger
> sizes. Rename it to soffset, to make it clear
> that the offset is applied to src.
>
> Also change the only usage of uint64_t in
> hw/9pfs/virtio-9p.c, in v9fs_init_qiov_from_pdu() -
> all callers of it actually uses size_t too,
> not uint64_t.
>
> One added restriction: as for all other iovec-related
> functions, soffset must point inside src.
>
> Order of argumens is already good:
> qemu_iovec_memset(QEMUIOVector *qiov, size_t offset,
> int c, size_t bytes)
> vs:
> qemu_iovec_concat(QEMUIOVector *dst,
> QEMUIOVector *src,
> size_t soffset, size_t sbytes)
> (note soffset is after _src_ not dst, since it applies to src;
> for memset it applies to qiov).
>
> Note that in many places where this function is used,
> the previous call is qemu_iovec_reset(), which means
> many callers actually want copy (replacing dst content),
> not concat. So we may want to add a wrapper like
> qemu_iovec_copy() with the same arguments but which
> calls qemu_iovec_reset() before _concat(). This needs
> to be done later, so that any current out-of-tree code
> which uses _copy().
>
> Signed-off-by: Michael Tokarev <address@hidden>
> ---
> block.c | 4 +-
> block/qcow2.c | 4 +-
> block/qed.c | 6 ++--
> cutils.c | 54 ++++++++++++++++++--------------------------------
> hw/9pfs/virtio-9p.c | 8 +++---
> qemu-common.h | 5 +--
> 6 files changed, 33 insertions(+), 48 deletions(-)
>
> diff --git a/block.c b/block.c
> index f4320be..9246518 100644
> --- a/block.c
> +++ b/block.c
> @@ -2959,13 +2959,13 @@ static int multiwrite_merge(BlockDriverState *bs,
> BlockRequest *reqs,
> // Add the first request to the merged one. If the requests are
> // overlapping, drop the last sectors of the first request.
> size = (reqs[i].sector - reqs[outidx].sector) << 9;
> - qemu_iovec_concat(qiov, reqs[outidx].qiov, size);
> + qemu_iovec_concat(qiov, reqs[outidx].qiov, 0, size);
>
> // We should need to add any zeros between the two requests
> assert (reqs[i].sector <= oldreq_last);
>
> // Add the second request
> - qemu_iovec_concat(qiov, reqs[i].qiov, reqs[i].qiov->size);
> + qemu_iovec_concat(qiov, reqs[i].qiov, 0, reqs[i].qiov->size);
>
> reqs[outidx].nb_sectors = qiov->size >> 9;
> reqs[outidx].qiov = qiov;
> diff --git a/block/qcow2.c b/block/qcow2.c
> index 106f2ce..894fb4d 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -445,7 +445,7 @@ static coroutine_fn int qcow2_co_readv(BlockDriverState
> *bs, int64_t sector_num,
> index_in_cluster = sector_num & (s->cluster_sectors - 1);
>
> qemu_iovec_reset(&hd_qiov);
> - qemu_iovec_copy(&hd_qiov, qiov, bytes_done,
> + qemu_iovec_concat(&hd_qiov, qiov, bytes_done,
> cur_nr_sectors * 512);
>
> if (!cluster_offset) {
> @@ -593,7 +593,7 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState
> *bs,
> assert((cluster_offset & 511) == 0);
>
> qemu_iovec_reset(&hd_qiov);
> - qemu_iovec_copy(&hd_qiov, qiov, bytes_done,
> + qemu_iovec_concat(&hd_qiov, qiov, bytes_done,
> cur_nr_sectors * 512);
>
> if (s->crypt_method) {
> diff --git a/block/qed.c b/block/qed.c
> index 6f9325b..a4ef12c 100644
> --- a/block/qed.c
> +++ b/block/qed.c
> @@ -1133,7 +1133,7 @@ static void qed_aio_write_alloc(QEDAIOCB *acb, size_t
> len)
>
> acb->cur_nclusters = qed_bytes_to_clusters(s,
> qed_offset_into_cluster(s, acb->cur_pos) + len);
> - qemu_iovec_copy(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
> + qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
>
> if (acb->flags & QED_AIOCB_ZERO) {
> /* Skip ahead if the clusters are already zero */
> @@ -1179,7 +1179,7 @@ static void qed_aio_write_inplace(QEDAIOCB *acb,
> uint64_t offset, size_t len)
>
> /* Calculate the I/O vector */
> acb->cur_cluster = offset;
> - qemu_iovec_copy(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
> + qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
>
> /* Do the actual write */
> qed_aio_write_main(acb, 0);
> @@ -1249,7 +1249,7 @@ static void qed_aio_read_data(void *opaque, int ret,
> goto err;
> }
>
> - qemu_iovec_copy(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
> + qemu_iovec_concat(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len);
>
> /* Handle zero cluster and backing file reads */
> if (ret == QED_CLUSTER_ZERO) {
> diff --git a/cutils.c b/cutils.c
> index 1c93ed4..b8fc954 100644
> --- a/cutils.c
> +++ b/cutils.c
> @@ -172,48 +172,34 @@ void qemu_iovec_add(QEMUIOVector *qiov, void *base,
> size_t len)
> }
>
> /*
> - * Copies iovecs from src to the end of dst. It starts copying after skipping
> - * the given number of bytes in src and copies until src is completely copied
> - * or the total size of the copied iovec reaches size.The size of the last
> - * copied iovec is changed in order to fit the specified total size if it
> isn't
> - * a perfect fit already.
> + * Concatenates (partial) iovecs from src to the end of dst.
> + * It starts copying after skipping `soffset' bytes at the
> + * beginning of src and adds individual vectors from src to
> + * dst copies up to `sbytes' bytes total, or up to the end
> + * of src if it comes first. This way, it is okay to specify
> + * very large value for `sbytes' to indicate "up to the end
> + * of src".
> + * Only vector pointers are processed, not the actual data buffers.
> */
> -void qemu_iovec_copy(QEMUIOVector *dst, QEMUIOVector *src, uint64_t skip,
> - size_t size)
> +void qemu_iovec_concat(QEMUIOVector *dst,
> + QEMUIOVector *src, size_t soffset, size_t sbytes)
> {
> int i;
> size_t done;
> - void *iov_base;
> - uint64_t iov_len;
> -
> + struct iovec *siov = src->iov;
> assert(dst->nalloc != -1);
> -
> - done = 0;
> - for (i = 0; (i < src->niov) && (done != size); i++) {
> - if (skip >= src->iov[i].iov_len) {
> - /* Skip the whole iov */
> - skip -= src->iov[i].iov_len;
> - continue;
> + assert(src->size >= soffset);
> + for (i = 0, done = 0; done < sbytes && i < src->niov; i++) {
> + if (soffset < siov[i].iov_len) {
> + size_t len = MIN(siov[i].iov_len - soffset, sbytes - done);
> + qemu_iovec_add(dst, siov[i].iov_base + soffset, len);
> + done += len;
> + soffset = 0;
> } else {
> - /* Skip only part (or nothing) of the iov */
> - iov_base = (uint8_t*) src->iov[i].iov_base + skip;
> - iov_len = src->iov[i].iov_len - skip;
> - skip = 0;
> + soffset -= siov[i].iov_len;
> }
> -
> - if (done + iov_len > size) {
> - qemu_iovec_add(dst, iov_base, size - done);
> - break;
> - } else {
> - qemu_iovec_add(dst, iov_base, iov_len);
> - }
> - done += iov_len;
> }
> -}
> -
> -void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t size)
> -{
> - qemu_iovec_copy(dst, src, 0, size);
> + /* return done; */
> }
>
> void qemu_iovec_destroy(QEMUIOVector *qiov)
> diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
> index c633fb9..f4a7026 100644
> --- a/hw/9pfs/virtio-9p.c
> +++ b/hw/9pfs/virtio-9p.c
> @@ -1648,7 +1648,7 @@ out:
> * with qemu_iovec_destroy().
> */
> static void v9fs_init_qiov_from_pdu(QEMUIOVector *qiov, V9fsPDU *pdu,
> - uint64_t skip, size_t size,
> + size_t skip, size_t size,
> bool is_write)
> {
> QEMUIOVector elem;
> @@ -1665,7 +1665,7 @@ static void v9fs_init_qiov_from_pdu(QEMUIOVector *qiov,
> V9fsPDU *pdu,
>
> qemu_iovec_init_external(&elem, iov, niov);
> qemu_iovec_init(qiov, niov);
> - qemu_iovec_copy(qiov, &elem, skip, size);
> + qemu_iovec_concat(qiov, &elem, skip, size);
> }
>
> static void v9fs_read(void *opaque)
> @@ -1715,7 +1715,7 @@ static void v9fs_read(void *opaque)
> qemu_iovec_init(&qiov, qiov_full.niov);
> do {
> qemu_iovec_reset(&qiov);
> - qemu_iovec_copy(&qiov, &qiov_full, count, qiov_full.size -
> count);
> + qemu_iovec_concat(&qiov, &qiov_full, count, qiov_full.size -
> count);
> if (0) {
> print_sg(qiov.iov, qiov.niov);
> }
> @@ -1970,7 +1970,7 @@ static void v9fs_write(void *opaque)
> qemu_iovec_init(&qiov, qiov_full.niov);
> do {
> qemu_iovec_reset(&qiov);
> - qemu_iovec_copy(&qiov, &qiov_full, total, qiov_full.size - total);
> + qemu_iovec_concat(&qiov, &qiov_full, total, qiov_full.size - total);
> if (0) {
> print_sg(qiov.iov, qiov.niov);
> }
> diff --git a/qemu-common.h b/qemu-common.h
> index 2cbb513..31b30b5 100644
> --- a/qemu-common.h
> +++ b/qemu-common.h
> @@ -333,9 +333,8 @@ typedef struct QEMUIOVector {
> void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint);
> void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int
> niov);
> void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len);
> -void qemu_iovec_copy(QEMUIOVector *dst, QEMUIOVector *src, uint64_t skip,
> - size_t size);
> -void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t size);
> +void qemu_iovec_concat(QEMUIOVector *dst,
> + QEMUIOVector *src, size_t soffset, size_t sbytes);
> void qemu_iovec_destroy(QEMUIOVector *qiov);
> void qemu_iovec_reset(QEMUIOVector *qiov);
> void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf);
Looks good.
Paolo
- [Qemu-devel] [PATCHv3 0/9] cleanup/consolidate some iovec functions, Michael Tokarev, 2012/03/12
- [Qemu-devel] [PATCHv3 2/9] consolidate qemu_iovec_memset{, _skip}() into single function and use existing iov_memset(), Michael Tokarev, 2012/03/12
- [Qemu-devel] [PATCHv3 1/9] refresh iov_* functions, Michael Tokarev, 2012/03/12
- [Qemu-devel] [PATCHv3 4/9] consolidate qemu_iovec_copy() and qemu_iovec_concat() and make them consistent, Michael Tokarev, 2012/03/12
- Re: [Qemu-devel] [PATCHv3 4/9] consolidate qemu_iovec_copy() and qemu_iovec_concat() and make them consistent,
Paolo Bonzini <=
- [Qemu-devel] [PATCHv3 5/9] change qemu_iovec_to_buf() to match other to, from_buf functions, Michael Tokarev, 2012/03/12
- [Qemu-devel] [PATCHv3 8/9] cleanup qemu_co_sendv(), qemu_co_recvv() and friends, Michael Tokarev, 2012/03/12
- [Qemu-devel] [PATCHv3 7/9] export qemu_sendv_recvv() and use it in qemu_sendv() and qemu_recvv(), Michael Tokarev, 2012/03/12
- [Qemu-devel] [PATCHv3 3/9] allow qemu_iovec_from_buffer() to specify offset from which to start copying, Michael Tokarev, 2012/03/12
- [Qemu-devel] [PATCHv3 6/9] change prototypes of qemu_sendv() and qemu_recvv(), Michael Tokarev, 2012/03/12