Signed-off-by: Dmitry Fleytman <dmi...@daynix.com> Signed-off-by: Yan Vugenfirer <y...@daynix.com> --- Makefile.objs | 1 + iov.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ iov.h | 13 +++++++++++++ tests/Makefile | 2 +- 4 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/Makefile.objs b/Makefile.objs index 593a592..5400c6c 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -43,6 +43,7 @@ coroutine-obj-$(CONFIG_WIN32) += coroutine-win32.o block-obj-y = iov.o cache-utils.o qemu-option.o module.o async.o block-obj-y += nbd.o block.o blockjob.o aes.o qemu-config.o +block-obj-y += net/checksum.o block-obj-y += thread-pool.o qemu-progress.o qemu-sockets.o uri.o notify.o block-obj-y += $(coroutine-obj-y) $(qobject-obj-y) $(version-obj-y) block-obj-$(CONFIG_POSIX) += event_notifier-posix.o aio-posix.o diff --git a/iov.c b/iov.c index a81eedc..c9fd128 100644 --- a/iov.c +++ b/iov.c @@ -17,6 +17,7 @@ */ #include "iov.h" +#include "net/checksum.h" #ifdef _WIN32 # include <windows.h> @@ -252,6 +253,58 @@ unsigned iov_copy(struct iovec *dst_iov, unsigned int dst_iov_cnt, return j; } +size_t iov_rebuild(struct iovec *dst, unsigned int dst_cnt, + const struct iovec *src, const unsigned int src_cnt, + size_t src_off) +{ + size_t curr_src_off = 0; + unsigned int i, j = 0; + + for (i = 0; i < src_cnt; i++) { + if (src_off < (curr_src_off + src[i].iov_len)) { + if (j == dst_cnt) { + return (size_t) -1; + } + + dst[j].iov_len = curr_src_off + src[i].iov_len - src_off; + dst[j].iov_base = src[i].iov_base + (src_off - curr_src_off); + + src_off += dst[j].iov_len; + j++; + } + curr_src_off += src[i].iov_len; + } + return j; +} + +uint32_t +iov_net_csum_add(const struct iovec *iov, const unsigned int iov_cnt, + size_t iov_off, size_t size) +{ + size_t iovec_off, buf_off; + unsigned int i; + uint32_t res = 0; + uint32_t seq = 0; + + iovec_off = 0; + buf_off = 0; + for (i = 0; i < iov_cnt && size; i++) { + if (iov_off < (iovec_off + iov[i].iov_len)) { + size_t len = MIN((iovec_off + iov[i].iov_len) - iov_off , size); + void *chunk_buf = iov[i].iov_base + (iov_off - iovec_off); + + res += net_checksum_add_cont(len, chunk_buf, seq); + seq += len; + + buf_off += len; + iov_off += len; + size -= len; + } + iovec_off += iov[i].iov_len; + } + return res; +} + /* io vectors */ void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint) diff --git a/iov.h b/iov.h index 34c8ec9..9439eb7 100644 --- a/iov.h +++ b/iov.h @@ -95,3 +95,16 @@ void iov_hexdump(const struct iovec *iov, const unsigned int iov_cnt, 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); + +/** + * Copy data between scatter-gather vectors + */ +size_t iov_rebuild(struct iovec *dest, unsigned int dest_cnt, + const struct iovec *src, const unsigned int src_cnt, + size_t src_off); + +/** + * Checksum calculation for scatter-gather vector + */ +uint32_t iov_net_csum_add(const struct iovec *iov, const unsigned int iov_cnt, + size_t iov_off, size_t size); diff --git a/tests/Makefile b/tests/Makefile index 9bf0765..8fb5241 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -49,7 +49,7 @@ tests/check-qlist$(EXESUF): tests/check-qlist.o qlist.o qint.o tests/check-qfloat$(EXESUF): tests/check-qfloat.o qfloat.o tests/check-qjson$(EXESUF): tests/check-qjson.o $(qobject-obj-y) qemu-tool.o tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(coroutine-obj-y) $(tools-obj-y) $(block-obj-y) iov.o -tests/test-iov$(EXESUF): tests/test-iov.o iov.o +tests/test-iov$(EXESUF): tests/test-iov.o iov.o net/checksum.o tests/test-qapi-types.c tests/test-qapi-types.h :\ $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py -- 1.7.11.7