[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