[PATCH] Cleanup patches for writev

Volker Lendecke Volker.Lendecke at SerNet.DE
Mon Dec 29 14:19:28 MST 2014


Hi!

Attached find some patches that consolidate cutting of bytes
from a short writev into a function iov_advance.

Review&push appreciated!

Thanks,

Volker

-- 
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
From e95929394fa96fa9466ce0d850869c30f1702bdd Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sat, 27 Dec 2014 12:24:13 +0000
Subject: [PATCH 1/5] lib: iov_buf does not need talloc.h anymore

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/lib/iov_buf.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/source3/lib/iov_buf.h b/source3/lib/iov_buf.h
index ec82909..397e906 100644
--- a/source3/lib/iov_buf.h
+++ b/source3/lib/iov_buf.h
@@ -21,7 +21,6 @@
 #define __LIB_IOV_BUF_H__
 
 #include <unistd.h>
-#include <talloc.h>
 #include <stdint.h>
 
 ssize_t iov_buflen(const struct iovec *iov, int iovlen);
-- 
1.9.1


From a46cb85b3bc5895d46ed7463f60c6649d91c107c Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sat, 27 Dec 2014 13:16:20 +0000
Subject: [PATCH 2/5] lib: Add iov_advance

This chops off n bytes from an iovec array. Used for short writev's

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/lib/iov_buf.c | 33 +++++++++++++++++++++++++++++++++
 source3/lib/iov_buf.h |  2 ++
 2 files changed, 35 insertions(+)

diff --git a/source3/lib/iov_buf.c b/source3/lib/iov_buf.c
index e05dfc9..f0e05a6 100644
--- a/source3/lib/iov_buf.c
+++ b/source3/lib/iov_buf.c
@@ -53,3 +53,36 @@ ssize_t iov_buf(const struct iovec *iov, int iovcnt,
 
 	return needed;
 }
+
+bool iov_advance(struct iovec **iov, int *iovcnt, size_t n)
+{
+	struct iovec *v = *iov;
+	int cnt = *iovcnt;
+
+	while (n > 0) {
+		if (cnt == 0) {
+			return false;
+		}
+		if (n < v->iov_len) {
+			v->iov_base = (char *)v->iov_base + n;
+			v->iov_len -= n;
+			break;
+		}
+		n -= v->iov_len;
+		v += 1;
+		cnt -= 1;
+	}
+
+	/*
+	 * Skip 0-length iovec's
+	 */
+
+	while ((cnt > 0) && (v->iov_len == 0)) {
+		v += 1;
+		cnt -= 1;
+	}
+
+	*iov = v;
+	*iovcnt = cnt;
+	return true;
+}
diff --git a/source3/lib/iov_buf.h b/source3/lib/iov_buf.h
index 397e906..8f0ca26 100644
--- a/source3/lib/iov_buf.h
+++ b/source3/lib/iov_buf.h
@@ -22,9 +22,11 @@
 
 #include <unistd.h>
 #include <stdint.h>
+#include <stdbool.h>
 
 ssize_t iov_buflen(const struct iovec *iov, int iovlen);
 ssize_t iov_buf(const struct iovec *iov, int iovcnt,
 		uint8_t *buf, size_t buflen);
+bool iov_advance(struct iovec **iov, int *iovcnt, size_t n);
 
 #endif
-- 
1.9.1


From add9783cd5873250a587063617ef0c6b1df48255 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sat, 27 Dec 2014 16:39:08 +0000
Subject: [PATCH 3/5] lib: Use iov_advance in writev_handler

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 lib/async_req/async_sock.c  | 34 +++++++++-------------------------
 lib/async_req/wscript_build |  2 +-
 2 files changed, 10 insertions(+), 26 deletions(-)

diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c
index 74b2cb7..b986e45 100644
--- a/lib/async_req/async_sock.c
+++ b/lib/async_req/async_sock.c
@@ -27,6 +27,7 @@
 #include <talloc.h>
 #include <tevent.h>
 #include "lib/async_req/async_sock.h"
+#include "lib/iov_buf.h"
 
 /* Note: lib/util/ is currently GPL */
 #include "lib/util/tevent_unix.h"
@@ -470,10 +471,8 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
 		private_data, struct tevent_req);
 	struct writev_state *state =
 		tevent_req_data(req, struct writev_state);
-	size_t to_write, written;
-	int i;
-
-	to_write = 0;
+	size_t written;
+	bool ok;
 
 	if ((state->flags & TEVENT_FD_READ) && (flags & TEVENT_FD_READ)) {
 		int ret, value;
@@ -507,10 +506,6 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
 		}
 	}
 
-	for (i=0; i<state->count; i++) {
-		to_write += state->iov[i].iov_len;
-	}
-
 	written = writev(state->fd, state->iov, state->count);
 	if ((written == -1) && (errno == EINTR)) {
 		/* retry */
@@ -526,26 +521,15 @@ static void writev_handler(struct tevent_context *ev, struct tevent_fd *fde,
 	}
 	state->total_size += written;
 
-	if (written == to_write) {
-		tevent_req_done(req);
+	ok = iov_advance(&state->iov, &state->count, written);
+	if (!ok) {
+		tevent_req_error(req, EIO);
 		return;
 	}
 
-	/*
-	 * We've written less than we were asked to, drop stuff from
-	 * state->iov.
-	 */
-
-	while (written > 0) {
-		if (written < state->iov[0].iov_len) {
-			state->iov[0].iov_base =
-				(char *)state->iov[0].iov_base + written;
-			state->iov[0].iov_len -= written;
-			break;
-		}
-		written -= state->iov[0].iov_len;
-		state->iov += 1;
-		state->count -= 1;
+	if (state->count == 0) {
+		tevent_req_done(req);
+		return;
 	}
 }
 
diff --git a/lib/async_req/wscript_build b/lib/async_req/wscript_build
index 7802935..e8af569 100644
--- a/lib/async_req/wscript_build
+++ b/lib/async_req/wscript_build
@@ -3,7 +3,7 @@
 
 bld.SAMBA_SUBSYSTEM('LIBASYNC_REQ',
 	source='async_sock.c',
-	public_deps='talloc tevent',
+	public_deps='talloc tevent iov_buf',
 	deps='tevent-util socket-blocking'
 	)
 
-- 
1.9.1


From e96eae084b7befce9b4f97bb5406b8ffc40556e5 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sat, 27 Dec 2014 16:48:55 +0000
Subject: [PATCH 4/5] lib: Use iov_advance in write_data_iov

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/lib/sys_rw_data.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/source3/lib/sys_rw_data.c b/source3/lib/sys_rw_data.c
index 353dbe7..88e5085 100644
--- a/source3/lib/sys_rw_data.c
+++ b/source3/lib/sys_rw_data.c
@@ -63,22 +63,12 @@ ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
 	iov = iov_copy;
 
 	while (sent < to_send) {
-		/*
-		 * We have to discard "thistime" bytes from the beginning
-		 * iov array, "thistime" contains the number of bytes sent
-		 * via writev last.
-		 */
-		while (thistime > 0) {
-			if (thistime < iov[0].iov_len) {
-				char *new_base =
-					(char *)iov[0].iov_base + thistime;
-				iov[0].iov_base = (void *)new_base;
-				iov[0].iov_len -= thistime;
-				break;
-			}
-			thistime -= iov[0].iov_len;
-			iov += 1;
-			iovcnt -= 1;
+		bool ok;
+
+		ok = iov_advance(&iov, &iovcnt, thistime);
+		if (!ok) {
+			errno = EIO;
+			return -1;
 		}
 
 		thistime = sys_writev(fd, iov, iovcnt);
-- 
1.9.1


From db82bf2fef1d52aba8137451fdc73a3fa9dc0ae6 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sat, 27 Dec 2014 16:51:32 +0000
Subject: [PATCH 5/5] lib: Fix a comment

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/lib/sys_rw_data.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/source3/lib/sys_rw_data.c b/source3/lib/sys_rw_data.c
index 88e5085..7198783 100644
--- a/source3/lib/sys_rw_data.c
+++ b/source3/lib/sys_rw_data.c
@@ -54,9 +54,7 @@ ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
 
 	/*
 	 * We could not send everything in one call. Make a copy of iov that
-	 * we can mess with. We keep a copy of the array start in iov_copy for
-	 * the TALLOC_FREE, because we're going to modify iov later on,
-	 * discarding elements.
+	 * we can mess with.
 	 */
 
 	memcpy(iov_copy, orig_iov, sizeof(struct iovec) * iovcnt);
-- 
1.9.1



More information about the samba-technical mailing list