From: Ralph Boehme Date: Tue, 19 Mar 2013 14:26:03 +0000 (+0100) Subject: Increase IO size when sendfile() is not used X-Git-Url: https://arthur.barton.de/gitweb/?p=netatalk.git;a=commitdiff_plain;h=023609beb221be242a4aca3bceee9d19e396f496 Increase IO size when sendfile() is not used If sendfile() support is disabled, the current code results in an IO size of 8k for transferring requested data to the client. Eg: - client request to read DSI quantum size bytes (~250k) from a file - afpd process loops read(8k, file) -> send(8k, client) until all 250k have been transferred This should be modified to read the whole 250k in one swoop from the file to a buffer and then send the whole buffer in one swoop to the client. From FR #76. --- diff --git a/NEWS b/NEWS index 3fe240b2..1f9f31c4 100644 --- a/NEWS +++ b/NEWS @@ -37,6 +37,8 @@ Changes in 3.0.3 Fixes bug #505. * UPD: Use FreeBSD sendfile() capability to send protocol header. From FR #75. +* UPD: Increase IO size when sendfile() is not used. + From FR #76. Changes in 3.0.2 ================ diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index ea6cbeec..4e47b91b 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -837,9 +837,9 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si } #endif - *rbuflen = MIN(reqcount, *rbuflen); + *rbuflen = MIN(reqcount, dsi->server_quantum); - cc = read_file(ofork, eid, offset, rbuf, rbuflen); + cc = read_file(ofork, eid, offset, ibuf, rbuflen); if (cc < 0) { err = cc; goto afp_read_done; @@ -856,18 +856,22 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si * we know that we're sending some data. if we fail, something * horrible happened. */ - if ((cc = dsi_readinit(dsi, rbuf, *rbuflen, reqcount, err)) < 0) + if ((cc = dsi_readinit(dsi, ibuf, *rbuflen, reqcount, err)) < 0) goto afp_read_exit; *rbuflen = cc; while (*rbuflen > 0) { - cc = read_file(ofork, eid, offset, rbuf, rbuflen); + /* + * This loop isn't really entered anymore, we've already + * sent the whole requested block in dsi_readinit(). + */ + cc = read_file(ofork, eid, offset, ibuf, rbuflen); if (cc < 0) goto afp_read_exit; offset += *rbuflen; /* dsi_read() also returns buffer size of next allocation */ - cc = dsi_read(dsi, rbuf, *rbuflen); /* send it off */ + cc = dsi_read(dsi, ibuf, *rbuflen); /* send it off */ if (cc < 0) goto afp_read_exit; *rbuflen = cc; diff --git a/libatalk/dsi/dsi_stream.c b/libatalk/dsi/dsi_stream.c index 7579e252..05c36fc8 100644 --- a/libatalk/dsi/dsi_stream.c +++ b/libatalk/dsi/dsi_stream.c @@ -523,6 +523,7 @@ int dsi_stream_send(DSI *dsi, void *buf, size_t length) { char block[DSI_BLOCKSIZ]; struct iovec iov[2]; + int iovecs = 2; size_t towrite; ssize_t len; @@ -549,7 +550,7 @@ int dsi_stream_send(DSI *dsi, void *buf, size_t length) towrite = sizeof(block) + length; dsi->write_count += towrite; while (towrite > 0) { - if (((len = writev(dsi->socket, iov, 2)) == -1 && errno == EINTR) || (len == 0)) + if (((len = writev(dsi->socket, iov, iovecs)) == -1 && errno == EINTR) || (len == 0)) continue; if ((size_t)len == towrite) /* wrote everything out */ @@ -570,12 +571,13 @@ int dsi_stream_send(DSI *dsi, void *buf, size_t length) iov[0].iov_base = (char *) iov[0].iov_base + len; iov[0].iov_len -= len; } else { /* skip to data */ - if (iov[0].iov_len) { + if (iovecs == 2) { + iovecs = 1; len -= iov[0].iov_len; - iov[0].iov_len = 0; + iov[0] = iov[1]; } - iov[1].iov_base = (char *) iov[1].iov_base + len; - iov[1].iov_len -= len; + iov[0].iov_base = (char *) iov[0].iov_base + len; + iov[0].iov_len -= len; } }