[PATCH kvmtool 10/24] Add memcpy_fromiovec_safe

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Existing IOV functions don't take the iovec size as parameter. This is
unfortunate because when parsing buffers split into header and body,
callers may want to know where the body starts in the iovec, after copying
the header. Add a function that does the same as memcpy_fromiovec, but
also allows to iterate over the iovec.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@xxxxxxx>
---
 include/kvm/iovec.h |  2 ++
 util/iovec.c        | 31 +++++++++++++++++++++++++++++++
 2 files changed, 33 insertions(+)

diff --git a/include/kvm/iovec.h b/include/kvm/iovec.h
index fe79dd48..55a03913 100644
--- a/include/kvm/iovec.h
+++ b/include/kvm/iovec.h
@@ -7,6 +7,8 @@ extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
 extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len);
 extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
 				size_t offset, int len);
+ssize_t memcpy_fromiovec_safe(void *buf, struct iovec **iov, size_t len,
+			      size_t *iovcount);
 
 static inline size_t iov_size(const struct iovec *iovec, size_t len)
 {
diff --git a/util/iovec.c b/util/iovec.c
index 089f1051..c0159011 100644
--- a/util/iovec.c
+++ b/util/iovec.c
@@ -93,6 +93,37 @@ int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len)
 	return 0;
 }
 
+/*
+ *	Copy at most @len bytes from iovec to buffer.
+ *	Returns the remaining len.
+ *
+ *	Note: this modifies the original iovec, the iov pointer, and the
+ *	iovcount to describe the remaining buffer.
+ */
+ssize_t memcpy_fromiovec_safe(void *buf, struct iovec **iov, size_t len,
+			      size_t *iovcount)
+{
+	size_t copy;
+
+	while (len && *iovcount) {
+		copy = min(len, (*iov)->iov_len);
+		memcpy(buf, (*iov)->iov_base, copy);
+		buf += copy;
+		len -= copy;
+
+		/* Move iov cursor */
+		(*iov)->iov_base += copy;
+		(*iov)->iov_len -= copy;
+
+		if (!(*iov)->iov_len) {
+			(*iov)++;
+			(*iovcount)--;
+		}
+	}
+
+	return len;
+}
+
 /*
  *	Copy iovec from kernel. Returns -EFAULT on error.
  */
-- 
2.36.1




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux