From dfa069dd2d7f705dc519e271eda87731f2b19529 Mon Sep 17 00:00:00 2001 Message-Id: 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:32 +0100 Subject: [PATCH 09/16] iov: add iov_discard_front/back() to remove data RH-Author: Stefan Hajnoczi Message-id: <1357138959-1918-10-git-send-email-stefanha@redhat.com> Patchwork-id: 45522 O-Subject: [RHEL6.4 qemu-kvm PATCH v5 09/16] iov: add iov_discard_front/back() to remove data Bugzilla: 877836 RH-Acked-by: Laszlo Ersek RH-Acked-by: Michael S. Tsirkin RH-Acked-by: Paolo Bonzini The iov_discard_front/back() functions remove data from the front or back of the vector. This is useful when peeling off header/footer structs. Signed-off-by: Stefan Hajnoczi --- hw/iov.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ hw/iov.h | 13 +++++++++++++ 2 files changed, 64 insertions(+) Signed-off-by: Michal Novotny --- hw/iov.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ hw/iov.h | 13 +++++++++++++ 2 files changed, 64 insertions(+) diff --git a/hw/iov.c b/hw/iov.c index 588cd04..1ffcc0e 100644 --- a/hw/iov.c +++ b/hw/iov.c @@ -68,3 +68,54 @@ size_t iov_size(const struct iovec *iov, const unsigned int iovcnt) } return len; } + +size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt, + size_t bytes) +{ + size_t total = 0; + struct iovec *cur; + + for (cur = *iov; *iov_cnt > 0; cur++) { + if (cur->iov_len > bytes) { + cur->iov_base += bytes; + cur->iov_len -= bytes; + total += bytes; + break; + } + + bytes -= cur->iov_len; + total += cur->iov_len; + *iov_cnt -= 1; + } + + *iov = cur; + return total; +} + +size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt, + size_t bytes) +{ + size_t total = 0; + struct iovec *cur; + + if (*iov_cnt == 0) { + return 0; + } + + cur = iov + (*iov_cnt - 1); + + while (*iov_cnt > 0) { + if (cur->iov_len > bytes) { + cur->iov_len -= bytes; + total += bytes; + break; + } + + bytes -= cur->iov_len; + total += cur->iov_len; + cur--; + *iov_cnt -= 1; + } + + return total; +} diff --git a/hw/iov.h b/hw/iov.h index 60a8547..0f56eff 100644 --- a/hw/iov.h +++ b/hw/iov.h @@ -17,3 +17,16 @@ size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt, 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); + +/* + * Remove a given number of bytes from the front or back of a vector. + * This may update iov and/or iov_cnt to exclude iovec elements that are + * no longer required. + * + * The number of bytes actually discarded is returned. This number may be + * smaller than requested if the vector is too small. + */ +size_t iov_discard_front(struct iovec **iov, unsigned int *iov_cnt, + size_t bytes); +size_t iov_discard_back(struct iovec *iov, unsigned int *iov_cnt, + size_t bytes); -- 1.7.11.7