From patchwork Fri Jul 1 07:42:50 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hannes Reinecke X-Patchwork-Id: 934722 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p617htAU015436 for ; Fri, 1 Jul 2011 07:43:55 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755298Ab1GAHnr (ORCPT ); Fri, 1 Jul 2011 03:43:47 -0400 Received: from cantor2.suse.de ([195.135.220.15]:40825 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755284Ab1GAHnq (ORCPT ); Fri, 1 Jul 2011 03:43:46 -0400 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id B97878980B; Fri, 1 Jul 2011 09:43:45 +0200 (CEST) From: Hannes Reinecke To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Stefan Haynoczi , kvm@vger.kernel.org, Alexander Graf , Hannes Reinecke Subject: [PATCH 1/3] iov: Add 'offset' parameter to iov_to_buf() Date: Fri, 1 Jul 2011 09:42:50 +0200 Message-Id: <1309506172-17762-2-git-send-email-hare@suse.de> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1309506172-17762-1-git-send-email-hare@suse.de> References: <1309506172-17762-1-git-send-email-hare@suse.de> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Fri, 01 Jul 2011 07:43:55 +0000 (UTC) Occasionally, the buffer needs to be placed at a offset within the iovec when copying the buffer to the iovec. Signed-off-by: Hannes Reinecke --- hw/virtio-net.c | 2 +- hw/virtio-serial-bus.c | 2 +- iov.c | 23 ++++++++++++++--------- iov.h | 2 +- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 6997e02..a32cc01 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -657,7 +657,7 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_ /* copy in packet. ugh */ len = iov_from_buf(sg, elem.in_num, - buf + offset, size - offset); + buf + offset, 0, size - offset); total += len; offset += len; /* If buffers can't be merged, at this point we diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c index 7f6db7b..53c58d0 100644 --- a/hw/virtio-serial-bus.c +++ b/hw/virtio-serial-bus.c @@ -103,7 +103,7 @@ static size_t write_to_port(VirtIOSerialPort *port, } len = iov_from_buf(elem.in_sg, elem.in_num, - buf + offset, size - offset); + buf + offset, 0, size - offset); offset += len; virtqueue_push(vq, &elem, len); diff --git a/iov.c b/iov.c index 588cd04..9ead6ee 100644 --- a/iov.c +++ b/iov.c @@ -15,21 +15,26 @@ #include "iov.h" size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt, - const void *buf, size_t size) + const void *buf, size_t offset, size_t size) { - size_t offset; + size_t iov_off, buf_off; unsigned int i; - offset = 0; - for (i = 0; offset < size && i < iovcnt; i++) { - size_t len; + iov_off = 0; + buf_off = 0; + for (i = 0; i < iovcnt && size; i++) { + if (offset < (iov_off + iov[i].iov_len)) { + size_t len = MIN((iov_off + iov[i].iov_len) - offset, size); - len = MIN(iov[i].iov_len, size - offset); + memcpy(iov[i].iov_base + (offset - iov_off), buf + buf_off, len); - memcpy(iov[i].iov_base, buf + offset, len); - offset += len; + buf_off += len; + offset += len; + size -= len; + } + iov_off += iov[i].iov_len; } - return offset; + return buf_off; } size_t iov_to_buf(const struct iovec *iov, const unsigned int iovcnt, diff --git a/iov.h b/iov.h index 60a8547..2677527 100644 --- a/iov.h +++ b/iov.h @@ -13,7 +13,7 @@ #include "qemu-common.h" size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt, - const void *buf, size_t size); + const void *buf, size_t offset, size_t size); size_t iov_to_buf(const struct iovec *iov, const unsigned int iovcnt, void *buf, size_t offset, size_t size); size_t iov_size(const struct iovec *iov, const unsigned int iovcnt);