From e4d5639dbb6181ebbfdb554f2594721b2d63882b Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Tue, 27 Apr 2010 18:04:05 +0530 Subject: [PATCH] iov: Introduce a new file for helpers around iovs, add iov_from_buf() The virtio-net code uses iov_fill() which fills an iov from a linear buffer. The virtio-serial-bus code does something similar in an open-coded function. Create a new iov.c file that has iov_from_buf(). Convert virtio-net and virtio-serial-bus over to use this functionality. virtio-net used ints to hold sizes, the new function is going to use size_t types. Later commits will add the opposite functionality -- going from an iov to a linear buffer. Signed-off-by: Amit Shah Signed-off-by: Anthony Liguori --- Makefile | 2 ++ Makefile.objs | 1 + hw/iov.c | 33 +++++++++++++++++++++++++++++++++ hw/iov.h | 16 ++++++++++++++++ hw/virtio-net.c | 20 +++----------------- hw/virtio-serial-bus.c | 15 +++++++-------- 6 files changed, 62 insertions(+), 25 deletions(-) create mode 100644 hw/iov.c create mode 100644 hw/iov.h diff --git a/Makefile b/Makefile index a404fdade6..18e736813f 100644 --- a/Makefile +++ b/Makefile @@ -124,6 +124,8 @@ curses.o: curses.c keymaps.h curses_keys.h bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS) +iov.o: iov.c iov.h + ###################################################################### qemu-img.o: qemu-img-cmds.h diff --git a/Makefile.objs b/Makefile.objs index 69d6879bfe..1c7c64b1d8 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -100,6 +100,7 @@ common-obj-y += keymaps.o common-obj-$(CONFIG_SDL) += sdl.o sdl_zoom.o x_keymap.o common-obj-$(CONFIG_CURSES) += curses.o common-obj-y += vnc.o acl.o d3des.o +common-obj-y += iov.o common-obj-$(CONFIG_VNC_TLS) += vnc-tls.o vnc-auth-vencrypt.o common-obj-$(CONFIG_VNC_SASL) += vnc-auth-sasl.o common-obj-$(CONFIG_COCOA) += cocoa.o diff --git a/hw/iov.c b/hw/iov.c new file mode 100644 index 0000000000..07bd499b0d --- /dev/null +++ b/hw/iov.c @@ -0,0 +1,33 @@ +/* + * Helpers for getting linearized buffers from iov / filling buffers into iovs + * + * Copyright IBM, Corp. 2007, 2008 + * Copyright (C) 2010 Red Hat, Inc. + * + * Author(s): + * Anthony Liguori + * Amit Shah + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#include "iov.h" + +size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt, + const void *buf, size_t size) +{ + size_t offset; + unsigned int i; + + offset = 0; + for (i = 0; offset < size && i < iovcnt; i++) { + size_t len; + + len = MIN(iov[i].iov_len, size - offset); + + memcpy(iov[i].iov_base, buf + offset, len); + offset += len; + } + return offset; +} diff --git a/hw/iov.h b/hw/iov.h new file mode 100644 index 0000000000..5e3e54123d --- /dev/null +++ b/hw/iov.h @@ -0,0 +1,16 @@ +/* + * Helpers for getting linearized buffers from iov / filling buffers into iovs + * + * Copyright (C) 2010 Red Hat, Inc. + * + * Author(s): + * Amit Shah + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#include "qemu-common.h" + +size_t iov_from_buf(struct iovec *iov, unsigned int iovcnt, + const void *buf, size_t size); diff --git a/hw/virtio-net.c b/hw/virtio-net.c index acb3cec7cb..d602c56c25 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -11,6 +11,7 @@ * */ +#include "iov.h" #include "virtio.h" #include "net.h" #include "net/checksum.h" @@ -445,21 +446,6 @@ static void work_around_broken_dhclient(struct virtio_net_hdr *hdr, } } -static int iov_fill(struct iovec *iov, int iovcnt, const void *buf, int count) -{ - int offset, i; - - offset = i = 0; - while (offset < count && i < iovcnt) { - int len = MIN(iov[i].iov_len, count - offset); - memcpy(iov[i].iov_base, buf + offset, len); - offset += len; - i++; - } - - return offset; -} - static int receive_header(VirtIONet *n, struct iovec *iov, int iovcnt, const void *buf, size_t size, size_t hdr_len) { @@ -595,8 +581,8 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_ } /* copy in packet. ugh */ - len = iov_fill(sg, elem.in_num, - buf + offset, size - offset); + len = iov_from_buf(sg, elem.in_num, + buf + offset, size - offset); total += len; /* signal other side */ diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c index 6befd4d139..a72b6b53d3 100644 --- a/hw/virtio-serial-bus.c +++ b/hw/virtio-serial-bus.c @@ -15,6 +15,7 @@ * the COPYING file in the top-level directory. */ +#include "iov.h" #include "monitor.h" #include "qemu-queue.h" #include "sysbus.h" @@ -84,27 +85,25 @@ static size_t write_to_port(VirtIOSerialPort *port, { VirtQueueElement elem; VirtQueue *vq; - size_t offset = 0; - size_t len = 0; + size_t offset; vq = port->ivq; if (!virtio_queue_ready(vq)) { return 0; } + offset = 0; while (offset < size) { - int i; + size_t len; if (!virtqueue_pop(vq, &elem)) { break; } - for (i = 0; offset < size && i < elem.in_num; i++) { - len = MIN(elem.in_sg[i].iov_len, size - offset); + len = iov_from_buf(elem.in_sg, elem.in_num, + buf + offset, size - offset); + offset += len; - memcpy(elem.in_sg[i].iov_base, buf + offset, len); - offset += len; - } virtqueue_push(vq, &elem, len); }