[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