]> arthur.barton.de Git - netatalk.git/commitdiff
Increase IO size when sendfile() is not used
authorRalph Boehme <sloowfranklin@gmail.com>
Tue, 19 Mar 2013 14:26:03 +0000 (15:26 +0100)
committerRalph Boehme <sloowfranklin@gmail.com>
Tue, 19 Mar 2013 14:26:03 +0000 (15:26 +0100)
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.

NEWS
etc/afpd/fork.c
libatalk/dsi/dsi_stream.c

diff --git a/NEWS b/NEWS
index 3fe240b2ae7a1df3d2bfe4965047fb33d89da7cb..1f9f31c4691e6df5fc4a8d2858efb0663ee4666c 100644 (file)
--- 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
 ================
index ea6cbeec2a6245ff6b5260c473db99c48d08522f..4e47b91b92a7ebd96d21987ebd82940e9a7990d5 100644 (file)
@@ -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;
index 7579e2520ef9894a512b7e40124ec75dbfe7a8ef..05c36fc8eaf290e06b62496f26ed60f6e8b8bce9 100644 (file)
@@ -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;
       }
   }