Message ID | a2b6d7e7a1190474b61b054dc483d03ba5e09f4a.1348527749.git.mst@redhat.com |
---|---|
State | New |
Headers | show |
"Michael S. Tsirkin" <mst@redhat.com> writes: > 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(+) > > diff --git a/iov.c b/iov.c > index c6a66f0..0dfcb28 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_cpy(struct iovec *dst_iov, unsigned int dst_iov_cnt, > + const struct iovec *iov, unsigned int iov_cnt, > + size_t offset, size_t bytes) I think the readability f the cde wuld be imprved if yu added the missing 'o' to iov_cpy. Otherwise: Reviewed-by: Anthony Liguori <aliguori@us.ibm.com> Regards, Anthony Liguori > +{ > + 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..f0daefa 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. Actual size is returned. > + */ > +size_t iov_cpy(struct iovec *dst_iov, unsigned int dst_iov_cnt, > + const struct iovec *iov, unsigned int iov_cnt, > + size_t offset, size_t bytes); > -- > MST
On Mon, Sep 24, 2012 at 07:34:00PM -0500, Anthony Liguori wrote: > "Michael S. Tsirkin" <mst@redhat.com> writes: > > > 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(+) > > > > diff --git a/iov.c b/iov.c > > index c6a66f0..0dfcb28 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_cpy(struct iovec *dst_iov, unsigned int dst_iov_cnt, > > + const struct iovec *iov, unsigned int iov_cnt, > > + size_t offset, size_t bytes) > > I think the readability f the cde wuld be imprved if yu added the > missing 'o' to iov_cpy. I was thinking about memcpy but maybe that's not a good model to follow. Will fix. > Otherwise: > > Reviewed-by: Anthony Liguori <aliguori@us.ibm.com> > > Regards, > > Anthony Liguori > > > +{ > > + 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..f0daefa 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. Actual size is returned. > > + */ > > +size_t iov_cpy(struct iovec *dst_iov, unsigned int dst_iov_cnt, > > + const struct iovec *iov, unsigned int iov_cnt, > > + size_t offset, size_t bytes); > > -- > > MST
diff --git a/iov.c b/iov.c index c6a66f0..0dfcb28 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_cpy(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..f0daefa 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. Actual size is returned. + */ +size_t iov_cpy(struct iovec *dst_iov, unsigned int dst_iov_cnt, + const struct iovec *iov, unsigned int iov_cnt, + size_t offset, size_t bytes);
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(+)