From 398bc1b6d18ba3a8c4a95985abaac021b23463d6 Mon Sep 17 00:00:00 2001 Message-Id: <398bc1b6d18ba3a8c4a95985abaac021b23463d6.1357726992.git.minovotn@redhat.com> In-Reply-To: <4f8efce613a639a3c1e3022c521d6c70b7154de8.1357726992.git.minovotn@redhat.com> References: <4f8efce613a639a3c1e3022c521d6c70b7154de8.1357726992.git.minovotn@redhat.com> From: Stefan Hajnoczi Date: Wed, 2 Jan 2013 15:02:33 +0100 Subject: [PATCH 10/16] iov: add qemu_iovec_concat_iov() RH-Author: Stefan Hajnoczi Message-id: <1357138959-1918-11-git-send-email-stefanha@redhat.com> Patchwork-id: 45523 O-Subject: [RHEL6.4 qemu-kvm PATCH v5 10/16] iov: add qemu_iovec_concat_iov() Bugzilla: 877836 RH-Acked-by: Laszlo Ersek RH-Acked-by: Michael S. Tsirkin RH-Acked-by: Paolo Bonzini The qemu_iovec_concat() function copies a subset of a QEMUIOVector. The new qemu_iovec_concat_iov() function does the same for a iov/cnt pair. Upstream defined qemu_iovec_concat() in terms of qemu_iovec_concat_iov() but the RHEL codebase has an older version of qemu_iovec_concat() which uses qemu_iovec_copy() and is therefore not easy to share. Conflicts: iov.c -> cutils.c Signed-off-by: Stefan Hajnoczi --- cutils.c | 30 ++++++++++++++++++++++++++++++ qemu-common.h | 3 +++ 2 files changed, 33 insertions(+) Signed-off-by: Michal Novotny --- cutils.c | 30 ++++++++++++++++++++++++++++++ qemu-common.h | 3 +++ 2 files changed, 33 insertions(+) diff --git a/cutils.c b/cutils.c index 7941325..9fb79fd 100644 --- a/cutils.c +++ b/cutils.c @@ -213,6 +213,36 @@ void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t size) qemu_iovec_copy(dst, src, 0, size); } +/* + * Concatenates (partial) iovecs from src_iov 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_iov 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_concat_iov(QEMUIOVector *dst, + struct iovec *src_iov, unsigned int src_cnt, + size_t soffset, size_t sbytes) +{ + int i; + size_t done; + assert(dst->nalloc != -1); + for (i = 0, done = 0; done < sbytes && i < src_cnt; i++) { + if (soffset < src_iov[i].iov_len) { + size_t len = MIN(src_iov[i].iov_len - soffset, sbytes - done); + qemu_iovec_add(dst, src_iov[i].iov_base + soffset, len); + done += len; + soffset = 0; + } else { + soffset -= src_iov[i].iov_len; + } + } + assert(soffset == 0); /* offset beyond end of src */ +} + void qemu_iovec_destroy(QEMUIOVector *qiov) { assert(qiov->nalloc != -1); diff --git a/qemu-common.h b/qemu-common.h index 03cd2b0..1f26638 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -276,6 +276,9 @@ 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_iov(QEMUIOVector *dst, + struct iovec *src_iov, unsigned int src_cnt, + 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); -- 1.7.11.7