@@ -107,6 +107,57 @@ size_t nbd_wr_sync(int fd, void *buffer, size_t
size, bool do_read)
return offset;
}
+int nbd_wr_aio(int sockfd, struct iovec *iov, size_t len, off_t
offset,
+ bool do_read)
+{
+ struct msghdr msg;
+ int ret, diff;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+
+ len += offset;
+
+ while (iov->iov_len < len) {
+ len -= iov->iov_len;
+
+ iov++;
+ msg.msg_iovlen++;
+ }
+
+ diff = iov->iov_len - len;
+ iov->iov_len -= diff;
+
+ while (msg.msg_iov->iov_len <= offset) {
+ offset -= msg.msg_iov->iov_len;
+
+ msg.msg_iov++;
+ msg.msg_iovlen--;
+ }
+
+ msg.msg_iov->iov_base = (char *) msg.msg_iov->iov_base + offset;
+ msg.msg_iov->iov_len -= offset;
+
+retry:
+ if (do_read) {
+ ret = recvmsg(sockfd, &msg, 0);
+ } else {
+ ret = sendmsg(sockfd, &msg, 0);
+ }
+
+ /* recoverable error */
+ if (ret == -1 && (errno == EAGAIN || errno == EINTR)) {
+ goto retry;
+ }
+
+ msg.msg_iov->iov_base = (char *) msg.msg_iov->iov_base - offset;
+ msg.msg_iov->iov_len += offset;
+
+ iov->iov_len += diff;
+ return ret;
+}
+
int tcp_socket_outgoing(const char *address, uint16_t port)
{
int s;
@@ -45,6 +45,8 @@ enum {
#define NBD_DEFAULT_PORT 10809
size_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read);
+int nbd_wr_aio(int sockfd, struct iovec *iov, size_t len, off_t
offset,
+ bool do_read);
int tcp_socket_outgoing(const char *address, uint16_t port);
int tcp_socket_incoming(const char *address, uint16_t port);
Signed-off-by: Nick Thomas <nick@bytemark.co.uk> --- nbd.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ nbd.h | 2 ++ 2 files changed, 53 insertions(+), 0 deletions(-) int unix_socket_outgoing(const char *path);