Patchwork [PATCHv2,03/14] iov: add iov_cpy

login
register
mail settings
Submitter Michael S. Tsirkin
Date Sept. 25, 2012, 11:12 a.m.
Message ID <b211a70080341375846c562d39d7ace1db8125cc.1348571185.git.mst@redhat.com>
Download mbox | patch
Permalink /patch/186788/
State New
Headers show

Comments

Michael S. Tsirkin - Sept. 25, 2012, 11:12 a.m.
Add API to copy part of iovec safely.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 iov.c | 23 +++++++++++++++++++++++
 iov.h |  9 +++++++++
 2 files changed, 32 insertions(+)

Patch

diff --git a/iov.c b/iov.c
index c6a66f0..b7378bf 100644
--- a/iov.c
+++ b/iov.c
@@ -228,3 +228,26 @@  void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt,
         fprintf(fp, "\n");
     }
 }
+
+unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
+                 const struct iovec *iov, unsigned int iov_cnt,
+                 size_t offset, size_t bytes)
+{
+    size_t len;
+    unsigned int i, j;
+    for (i = 0, j = 0; i < iov_cnt && j < dst_iov_cnt && bytes; i++) {
+        if (offset >= iov[i].iov_len) {
+            offset -= iov[i].iov_len;
+            continue;
+        }
+        len = MIN(bytes, iov[i].iov_len - offset);
+
+        dst_iov[j].iov_base = iov[i].iov_base + offset;
+        dst_iov[j].iov_len = len;
+        j++;
+        bytes -= len;
+        offset = 0;
+    }
+    assert(offset == 0);
+    return j;
+}
diff --git a/iov.h b/iov.h
index a73569f..34c8ec9 100644
--- a/iov.h
+++ b/iov.h
@@ -86,3 +86,12 @@  ssize_t iov_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt,
  */
 void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt,
                  FILE *fp, const char *prefix, size_t limit);
+
+/*
+ * Partial copy of vector from iov to dst_iov (data is not copied).
+ * dst_iov overlaps iov at a specified offset.
+ * size of dst_iov is at most bytes. dst vector count is returned.
+ */
+unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt,
+                 const struct iovec *iov, unsigned int iov_cnt,
+                 size_t offset, size_t bytes);