From 3d9b49254f893f2a3739400e536de25db1cdc5f9 Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Sat, 10 Mar 2012 16:54:23 +0400 Subject: consolidate qemu_iovec_memset{,_skip}() into single function and use existing iov_memset() This patch combines two functions into one, and replaces the implementation with already existing iov_memset() from iov.c. The new prototype of qemu_iovec_memset(): size_t qemu_iovec_memset(qiov, size_t offset, int fillc, size_t bytes) It is different from former qemu_iovec_memset_skip(), and I want to make other functions to be consistent with it too: first how much to skip, second what, and 3rd how many of it. It also returns actual number of bytes filled in, which may be less than the requested `bytes' if qiov is smaller than offset+bytes, in the same way iov_memset() does. While at it, use utility function iov_memset() from iov.h in posix-aio-compat.c, where qiov was used. Signed-off-by: Michael Tokarev --- qemu-common.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'qemu-common.h') diff --git a/qemu-common.h b/qemu-common.h index 91e0562..e752d2b 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -347,9 +347,8 @@ void qemu_iovec_destroy(QEMUIOVector *qiov); void qemu_iovec_reset(QEMUIOVector *qiov); void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf); void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf, size_t count); -void qemu_iovec_memset(QEMUIOVector *qiov, int c, size_t count); -void qemu_iovec_memset_skip(QEMUIOVector *qiov, int c, size_t count, - size_t skip); +size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset, + int fillc, size_t bytes); bool buffer_is_zero(const void *buf, size_t len); -- cgit v1.1 From 03396148bca54c0e81ad8eecb12a136456d14c16 Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Thu, 7 Jun 2012 20:17:55 +0400 Subject: allow qemu_iovec_from_buffer() to specify offset from which to start copying Similar to qemu_iovec_memset(QEMUIOVector *qiov, size_t offset, int c, size_t bytes); the new prototype is: qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset, const void *buf, size_t bytes); The processing starts at offset bytes within qiov. This way, we may copy a bounce buffer directly to a middle of qiov. This is exactly the same function as iov_from_buf() from iov.c, so use the existing implementation and rename it to qemu_iovec_from_buf() to be shorter and to match the utility function. As with utility implementation, we now assert that the offset is inside actual iovec. Nothing changed for current callers, because `offset' parameter is new. While at it, stop using "bounce-qiov" in block/qcow2.c and copy decrypted data directly from cluster_data instead of recreating a temp qiov for doing that. Signed-off-by: Michael Tokarev --- qemu-common.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'qemu-common.h') diff --git a/qemu-common.h b/qemu-common.h index e752d2b..430ec15 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -346,7 +346,8 @@ void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t size); void qemu_iovec_destroy(QEMUIOVector *qiov); void qemu_iovec_reset(QEMUIOVector *qiov); void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf); -void qemu_iovec_from_buffer(QEMUIOVector *qiov, const void *buf, size_t count); +size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset, + const void *buf, size_t bytes); size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset, int fillc, size_t bytes); -- cgit v1.1 From 1b093c480a32051cc856b6ab2395d8cbc3ae99da Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Mon, 12 Mar 2012 21:28:06 +0400 Subject: consolidate qemu_iovec_copy() and qemu_iovec_concat() and make them consistent qemu_iovec_concat() is currently a wrapper for qemu_iovec_copy(), use the former (with extra "0" arg) in a few places where it is used. Change skip argument of qemu_iovec_copy() from uint64_t to size_t, since size of qiov itself is size_t, so there's no way to skip larger sizes. Rename it to soffset, to make it clear that the offset is applied to src. Also change the only usage of uint64_t in hw/9pfs/virtio-9p.c, in v9fs_init_qiov_from_pdu() - all callers of it actually uses size_t too, not uint64_t. One added restriction: as for all other iovec-related functions, soffset must point inside src. Order of argumens is already good: qemu_iovec_memset(QEMUIOVector *qiov, size_t offset, int c, size_t bytes) vs: qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t soffset, size_t sbytes) (note soffset is after _src_ not dst, since it applies to src; for memset it applies to qiov). Note that in many places where this function is used, the previous call is qemu_iovec_reset(), which means many callers actually want copy (replacing dst content), not concat. So we may want to add a wrapper like qemu_iovec_copy() with the same arguments but which calls qemu_iovec_reset() before _concat(). Signed-off-by: Michael Tokarev --- qemu-common.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'qemu-common.h') diff --git a/qemu-common.h b/qemu-common.h index 430ec15..cae7bb6 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -340,9 +340,8 @@ typedef struct QEMUIOVector { void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint); void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int niov); void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len); -void qemu_iovec_copy(QEMUIOVector *dst, QEMUIOVector *src, uint64_t skip, - size_t size); -void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t size); +void qemu_iovec_concat(QEMUIOVector *dst, + QEMUIOVector *src, size_t soffset, size_t sbytes); void qemu_iovec_destroy(QEMUIOVector *qiov); void qemu_iovec_reset(QEMUIOVector *qiov); void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf); -- cgit v1.1 From d5e6b1619c516fa1e2ee4d8d20f08fcda4fb67a0 Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Thu, 7 Jun 2012 20:21:06 +0400 Subject: change qemu_iovec_to_buf() to match other to,from_buf functions It now allows specifying offset within qiov to start from and amount of bytes to copy. Actual implementation is just a call to iov_to_buf(). Signed-off-by: Michael Tokarev --- qemu-common.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'qemu-common.h') diff --git a/qemu-common.h b/qemu-common.h index cae7bb6..056e495 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -344,7 +344,8 @@ void qemu_iovec_concat(QEMUIOVector *dst, QEMUIOVector *src, size_t soffset, size_t sbytes); void qemu_iovec_destroy(QEMUIOVector *qiov); void qemu_iovec_reset(QEMUIOVector *qiov); -void qemu_iovec_to_buffer(QEMUIOVector *qiov, void *buf); +size_t qemu_iovec_to_buf(QEMUIOVector *qiov, size_t offset, + void *buf, size_t bytes); size_t qemu_iovec_from_buf(QEMUIOVector *qiov, size_t offset, const void *buf, size_t bytes); size_t qemu_iovec_memset(QEMUIOVector *qiov, size_t offset, -- cgit v1.1 From 3e80bf9351f8fec9085c46df6da075efd5e71003 Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Sat, 10 Mar 2012 17:00:41 +0400 Subject: rename qemu_sendv to iov_send, change proto and move declarations to iov.h Rename arguments and use size_t for sizes instead of int, from int qemu_sendv(int sockfd, struct iovec *iov, int len, int iov_offset) to ssize_t iov_send(int sockfd, struct iovec *iov, size_t offset, size_t bytes) The main motivation was to make it clear that length and offset are in _bytes_, not in iov elements: it was very confusing before, because all standard functions which deals with iovecs expects number of iovs, not bytes, even the fact that struct iovec has iov_len and iov_ prefix does not help. With "bytes" and "offset", especially since they're now size_t, it is much more explicit. Also change the return type to be ssize_t instead of int. This also changes it to match other iov-related functons, but not _quite_: there's still no argument indicating where iovec ends, ie, no iov_cnt parameter as used in iov_size() and friends. If will be added in subsequent patch/rewrite. All callers of qemu_sendv() and qemu_recvv() and related, like qemu_co_sendv() and qemu_co_recvv(), were checked to verify that it is safe to use unsigned datatype instead of int. Note that the order of arguments is changed to: offset and bytes (len and iov_offset) are swapped with each other. This is to make them consistent with very similar functions from qemu_iovec family, where offset always follows qiov, to mean the place in it to start from. Signed-off-by: Michael Tokarev --- qemu-common.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'qemu-common.h') diff --git a/qemu-common.h b/qemu-common.h index 056e495..41b8ae7 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -205,9 +205,6 @@ int qemu_pipe(int pipefd[2]); #define qemu_recv(sockfd, buf, len, flags) recv(sockfd, buf, len, flags) #endif -int qemu_recvv(int sockfd, struct iovec *iov, int len, int iov_offset); -int qemu_sendv(int sockfd, struct iovec *iov, int len, int iov_offset); - /* Error handling. */ void QEMU_NORETURN hw_error(const char *fmt, ...) GCC_FMT_ATTR(1, 2); -- cgit v1.1 From 2fc8ae1dd77fbc55146b602f703add6dc314dea4 Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Thu, 7 Jun 2012 20:22:46 +0400 Subject: cleanup qemu_co_sendv(), qemu_co_recvv() and friends The same as for non-coroutine versions in previous patches: rename arguments to be more obvious, change type of arguments from int to size_t where appropriate, and use common code for send and receive paths (with one extra argument) since these are exactly the same. Use common iov_send_recv() directly. qemu_co_sendv(), qemu_co_recvv(), and qemu_co_recv() are now trivial #define's merely adding one extra arg. qemu_co_sendv() and qemu_co_recvv() callers are converted to different argument order and extra `iov_cnt' argument. Signed-off-by: Michael Tokarev --- qemu-common.h | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) (limited to 'qemu-common.h') diff --git a/qemu-common.h b/qemu-common.h index 41b8ae7..7139577 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -300,32 +300,29 @@ struct qemu_work_item { void qemu_init_vcpu(void *env); #endif -/** - * Sends an iovec (or optionally a part of it) down a socket, yielding - * when the socket is full. - */ -int qemu_co_sendv(int sockfd, struct iovec *iov, - int len, int iov_offset); /** - * Receives data into an iovec (or optionally into a part of it) from - * a socket, yielding when there is no data in the socket. + * Sends a (part of) iovec down a socket, yielding when the socket is full, or + * Receives data into a (part of) iovec from a socket, + * yielding when there is no data in the socket. + * The same interface as qemu_sendv_recvv(), with added yielding. + * XXX should mark these as coroutine_fn */ -int qemu_co_recvv(int sockfd, struct iovec *iov, - int len, int iov_offset); - +ssize_t qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt, + size_t offset, size_t bytes, bool do_send); +#define qemu_co_recvv(sockfd, iov, iov_cnt, offset, bytes) \ + qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, false) +#define qemu_co_sendv(sockfd, iov, iov_cnt, offset, bytes) \ + qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, true) /** - * Sends a buffer down a socket, yielding when the socket is full. + * The same as above, but with just a single buffer */ -int qemu_co_send(int sockfd, void *buf, int len); - -/** - * Receives data into a buffer from a socket, yielding when there - * is no data in the socket. - */ -int qemu_co_recv(int sockfd, void *buf, int len); - +ssize_t qemu_co_send_recv(int sockfd, void *buf, size_t bytes, bool do_send); +#define qemu_co_recv(sockfd, buf, bytes) \ + qemu_co_send_recv(sockfd, buf, bytes, false) +#define qemu_co_send(sockfd, buf, bytes) \ + qemu_co_send_recv(sockfd, buf, bytes, true) typedef struct QEMUIOVector { struct iovec *iov; -- cgit v1.1