net engine: cleanup the splice handling

The splice and vmsplice bits were largely duplicated, so abstract
the stuff out so it's clearer to see what is going on.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
diff --git a/engines/net.c b/engines/net.c
index 4538a04..52e3b04 100644
--- a/engines/net.c
+++ b/engines/net.c
@@ -52,18 +52,12 @@
 	return 1;
 }
 
-/*
- * Receive bytes from a socket and fill them into the internal pipe
- */
-static int splice_in(struct thread_data *td, struct io_u *io_u)
+static int splice_io_u(int fdin, int fdout, unsigned int len)
 {
-	struct netio_data *nd = td->io_ops->data;
-	unsigned int len = io_u->xfer_buflen;
-	struct fio_file *f = io_u->file;
 	int bytes = 0;
 
 	while (len) {
-		int ret = splice(f->fd, NULL, nd->pipes[1], NULL, len, 0);
+		int ret = splice(fdin, NULL, fdout, NULL, len, 0);
 
 		if (ret < 0) {
 			if (!bytes)
@@ -81,31 +75,51 @@
 }
 
 /*
+ * Receive bytes from a socket and fill them into the internal pipe
+ */
+static int splice_in(struct thread_data *td, struct io_u *io_u)
+{
+	struct netio_data *nd = td->io_ops->data;
+
+	return splice_io_u(io_u->file->fd, nd->pipes[1], io_u->xfer_buflen);
+}
+
+/*
  * Transmit 'len' bytes from the internal pipe
  */
 static int splice_out(struct thread_data *td, struct io_u *io_u,
 		      unsigned int len)
 {
 	struct netio_data *nd = td->io_ops->data;
-	struct fio_file *f = io_u->file;
+
+	return splice_io_u(nd->pipes[0], io_u->file->fd, len);
+}
+
+static int vmsplice_io_u(struct io_u *io_u, int fd, unsigned int len)
+{
+	struct iovec iov = {
+		.iov_base = io_u->xfer_buf,
+		.iov_len = len,
+	};
 	int bytes = 0;
 
-	while (len) {
-		int ret = splice(nd->pipes[0], NULL, f->fd, NULL, len, 0);
+	while (iov.iov_len) {
+		int ret = vmsplice(fd, &iov, 1, SPLICE_F_MOVE);
 
 		if (ret < 0) {
 			if (!bytes)
 				bytes = ret;
-			
 			break;
 		} else if (!ret)
 			break;
 
+		iov.iov_len -= ret;
+		iov.iov_base += ret;
 		bytes += ret;
-		len -= ret;
 	}
 
 	return bytes;
+
 }
 
 /*
@@ -115,29 +129,8 @@
 			     unsigned int len)
 {
 	struct netio_data *nd = td->io_ops->data;
-	struct iovec iov = {
-		.iov_base = io_u->xfer_buf,
-		.iov_len = len,
-	};
-	int bytes = 0;
 
-	while (iov.iov_len) {
-		int ret = vmsplice(nd->pipes[0], &iov, 1, SPLICE_F_MOVE);
-
-		if (ret < 0) {
-			if (!bytes)
-				bytes = ret;
-			break;
-		} else if (!ret)
-			break;
-
-		iov.iov_len -= ret;
-		bytes += ret;
-		if (iov.iov_len)
-			iov.iov_base += ret;
-	}
-
-	return bytes;
+	return vmsplice_io_u(io_u, nd->pipes[0], len);
 }
 
 /*
@@ -146,49 +139,38 @@
 static int vmsplice_io_u_in(struct thread_data *td, struct io_u *io_u)
 {
 	struct netio_data *nd = td->io_ops->data;
-	struct iovec iov = {
-		.iov_base = io_u->xfer_buf,
-		.iov_len = io_u->xfer_buflen,
-	};
-	unsigned int bytes = 0;
 
-	while (iov.iov_len) {
-		int ret = vmsplice(nd->pipes[1], &iov, 1, SPLICE_F_MOVE);
-
-		if (ret < 0)
-			return -1;
-		else if (!ret)
-			return bytes;
-
-		iov.iov_len -= ret;
-		bytes += ret;
-		if (iov.iov_len)
-			iov.iov_base += ret;
-	}
-
-	return bytes;
+	return vmsplice_io_u(io_u, nd->pipes[1], io_u->xfer_buflen);
 }
 
+/*
+ * splice receive - transfer socket data into a pipe using splice, then map
+ * that pipe data into the io_u using vmsplice.
+ */
 static int fio_netio_splice_in(struct thread_data *td, struct io_u *io_u)
 {
 	int ret;
 
 	ret = splice_in(td, io_u);
-	if (ret <= 0)
-		return ret;
+	if (ret > 0)
+		return vmsplice_io_u_out(td, io_u, ret);
 
-	return vmsplice_io_u_out(td, io_u, ret);
+	return ret;
 }
 
+/*
+ * splice transmit - map data from the io_u into a pipe by using vmsplice,
+ * then transfer that pipe to a socket using splice.
+ */
 static int fio_netio_splice_out(struct thread_data *td, struct io_u *io_u)
 {
 	int ret;
 
 	ret = vmsplice_io_u_in(td, io_u);
-	if (ret <= 0)
-		return ret;
+	if (ret > 0)
+		return splice_out(td, io_u, ret);
 
-	return splice_out(td, io_u, ret);
+	return ret;
 }
 
 static int fio_netio_send(struct thread_data *td, struct io_u *io_u)
@@ -306,7 +288,6 @@
 	return 0;
 }
 
-
 static int fio_netio_open_file(struct thread_data *td, struct fio_file *f)
 {
 	if (td_read(td))