[Sheepdog] [PATCH] sheepdog: clean up do_readv_writev

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Thu Apr 29 01:27:58 CEST 2010


What we want to do here is to process iovec buffers
without changing its contents. This patch refactors the
function.

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 block/sheepdog.c |   93 +++++++++++++++++++++++++-----------------------------
 1 files changed, 43 insertions(+), 50 deletions(-)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 02850ef..b77b249 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -502,76 +502,69 @@ success:
 	return fd;
 }
 
-static void reset_iov(struct msghdr *msg, int len)
+static int do_send_recv(int sockfd, struct iovec *iov, int len, int offset,
+			int write)
 {
-	msg->msg_iov->iov_base = (char *) msg->msg_iov->iov_base - len;
-	msg->msg_iov->iov_len += len;
-}
+	struct msghdr msg;
+	int ret, diff;
 
-static int forward_iov(struct msghdr *msg, int len)
-{
-	while (msg->msg_iov->iov_len <= len) {
-		len -= msg->msg_iov->iov_len;
-		msg->msg_iov++;
-		msg->msg_iovlen--;
-	}
+	memset(&msg, 0, sizeof(msg));
+	msg.msg_iov = iov;
+	msg.msg_iovlen = 1;
 
-	msg->msg_iov->iov_base = (char *) msg->msg_iov->iov_base + len;
-	msg->msg_iov->iov_len -= len;
+	len += offset;
 
-	return len;
-}
+	while (iov->iov_len < len) {
+		len -= iov->iov_len;
 
-static int set_iov_limit(struct iovec *iov, int len, int *diff)
-{
-	int i = 0;
+		iov++;
+		msg.msg_iovlen++;
+	}
 
-	for (i = 0; iov[i].iov_len < len; i++)
-		len -= iov[i].iov_len;
+	diff = iov->iov_len - len;
+	iov->iov_len -= diff;
 
-	*diff = iov[i].iov_len - len;
-	iov[i].iov_len = len;
+	while (msg.msg_iov->iov_len <= offset) {
+		offset -= msg.msg_iov->iov_len;
 
-	return i + 1;
-}
+		msg.msg_iov++;
+		msg.msg_iovlen--;
+	}
 
-static int do_readv_writev(int sockfd, struct iovec *iov, int len,
-			   int iov_offset, int write)
-{
-	int ret, diff;
-	struct iovec *end_iov;
-	struct msghdr msg;
+	msg.msg_iov->iov_base = (char *) msg.msg_iov->iov_base + offset;
+	msg.msg_iov->iov_len -= offset;
 
-	memset(&msg, 0, sizeof(msg));
-	msg.msg_iov = iov;
-	msg.msg_iovlen = set_iov_limit(msg.msg_iov, iov_offset + len, &diff);
-	end_iov = &msg.msg_iov[msg.msg_iovlen - 1];
-reread:
-	iov_offset = forward_iov(&msg, iov_offset);
 	if (write)
 		ret = sendmsg(sockfd, &msg, 0);
 	else
 		ret = recvmsg(sockfd, &msg, MSG_WAITALL);
-	reset_iov(&msg, iov_offset);
-	if (ret <= 0) {
+
+	msg.msg_iov->iov_base = (char *) msg.msg_iov->iov_base - offset;
+	msg.msg_iov->iov_len += offset;
+
+	iov->iov_len += diff;
+	return ret;
+}
+
+static int do_readv_writev(int sockfd, struct iovec *iov, int len,
+			   int iov_offset, int write)
+{
+	int ret;
+again:
+	ret = do_send_recv(sockfd, iov, len, iov_offset, write);
+	if (ret < 0) {
 		if (errno == EINTR || errno == EAGAIN)
-			goto reread;
+			goto again;
 		eprintf("failed to recv a rsp, %m\n");
-		ret = 1;
-		goto out;
+		return 1;
 	}
 
+	iov_offset += ret;
 	len -= ret;
-	if (len) {
-		iov_offset += ret;
-		goto reread;
-	}
+	if (len)
+		goto again;
 
-	ret = 0;
-out:
-	/* reset iovec state */
-	end_iov->iov_len += diff;
-	return ret;
+	return 0;
 }
 
 static int do_readv(int sockfd, struct iovec *iov, int len, int iov_offset)
-- 
1.5.6.5




More information about the sheepdog mailing list