]> arthur.barton.de Git - netatalk.git/commitdiff
on linux put sendfile back
authordidg <didg>
Sun, 25 Oct 2009 09:47:03 +0000 (09:47 +0000)
committerdidg <didg>
Sun, 25 Oct 2009 09:47:03 +0000 (09:47 +0000)
configure.in
etc/afpd/desktop.c
etc/afpd/fork.c
include/atalk/adouble.h
include/atalk/dsi.h
libatalk/adouble/ad_sendfile.c
libatalk/dsi/dsi_stream.c

index 70b3f3e0e0167d37d079304ed27dbbef9281de09..b643b90b2ea02d60b35b93790b1059b2a0cc0a20 100644 (file)
@@ -1,4 +1,4 @@
-dnl $Id: configure.in,v 1.222 2009-10-23 14:09:50 franklahm Exp $
+dnl $Id: configure.in,v 1.223 2009-10-25 09:47:03 didg Exp $
 dnl configure.in for netatalk
 
 AC_INIT(etc/afpd/main.c)
 dnl configure.in for netatalk
 
 AC_INIT(etc/afpd/main.c)
@@ -708,15 +708,14 @@ fi
        AC_DEFINE(HAVE_BROKEN_DBTOB, 1, [Define if dbtob is broken])
 
        netatalk_cv_linux_sendfile=no
        AC_DEFINE(HAVE_BROKEN_DBTOB, 1, [Define if dbtob is broken])
 
        netatalk_cv_linux_sendfile=no
-dnl    disable this for now, code doesn't use sendfile anyway
-dnl        AC_ARG_ENABLE(sendfile,
-dnl        [  --enable-sendfile       use sendfile syscall default (no) ],[
-dnl            if test "$enableval" = "yes"; then
-dnl                    netatalk_cv_linux_sendfile=yes
-dnl            fi
-dnl            AC_MSG_RESULT([enabling sendfile syscall])
-dnl        ]
-dnl       )
+        AC_ARG_ENABLE(sendfile,
+           [  --enable-sendfile       use sendfile syscall default (no) ],[
+               if test "$enableval" = "yes"; then
+                       netatalk_cv_linux_sendfile=yes
+               fi
+               AC_MSG_RESULT([enabling sendfile syscall])
+           ]
+       )
 
        if test x"$netatalk_cv_linux_sendfile" = "xyes"; then 
            AC_CACHE_CHECK([for linux sendfile support],netatalk_cv_HAVE_SENDFILE,[
 
        if test x"$netatalk_cv_linux_sendfile" = "xyes"; then 
            AC_CACHE_CHECK([for linux sendfile support],netatalk_cv_HAVE_SENDFILE,[
index 060b68dc20425bfc424a483357680772ce3859d8..af2264479d2d07af9b9d141492f5bf12eb2eb390 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: desktop.c,v 1.42 2009-10-22 13:40:11 franklahm Exp $
+ * $Id: desktop.c,v 1.43 2009-10-25 09:47:03 didg Exp $
  *
  * See COPYRIGHT.
  *
  *
  * See COPYRIGHT.
  *
@@ -506,7 +506,7 @@ int afp_geticon(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
         while (*rbuflen > 0) {
 #ifdef WITH_SENDFILE
             if (!obj->options.flags & OPTION_DEBUG) {
         while (*rbuflen > 0) {
 #ifdef WITH_SENDFILE
             if (!obj->options.flags & OPTION_DEBUG) {
-                if (sys_sendfile(dsi->socket, si.sdt_fd, &offset, dsi->datasize) < 0) {
+                if (dsi_stream_read_file(dsi, si.sdt_fd, offset, dsi->datasize) < 0) {
                     switch (errno) {
                     case ENOSYS:
                     case EINVAL:  /* there's no guarantee that all fs support sendfile */
                     switch (errno) {
                     case ENOSYS:
                     case EINVAL:  /* there's no guarantee that all fs support sendfile */
@@ -515,7 +515,10 @@ int afp_geticon(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
                         goto geticon_exit;
                     }
                 }
                         goto geticon_exit;
                     }
                 }
-                goto geticon_done;
+                else {
+                    dsi_readdone(dsi);
+                    return AFP_OK;
+                }
             }
 #endif
             buflen = read(si.sdt_fd, rbuf, *rbuflen);
             }
 #endif
             buflen = read(si.sdt_fd, rbuf, *rbuflen);
@@ -529,7 +532,7 @@ int afp_geticon(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t
 
             *rbuflen = buflen;
         }
 
             *rbuflen = buflen;
         }
-
+        
         dsi_readdone(dsi);
         return AFP_OK;
 
         dsi_readdone(dsi);
         return AFP_OK;
 
index 07ce3ab19f6e3a91ba69d4afef569cbf964df1a3..3c1e8756b82c1f7b3bd98207804aa8c39623ebb3 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: fork.c,v 1.68 2009-10-25 06:12:51 didg Exp $
+ * $Id: fork.c,v 1.69 2009-10-25 09:47:04 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -931,10 +931,12 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si
         *rbuflen = cc;
         /* due to the nature of afp packets, we have to exit if we get
            an error. we can't do this with translation on. */
         *rbuflen = cc;
         /* due to the nature of afp packets, we have to exit if we get
            an error. we can't do this with translation on. */
-#if 0 /* ifdef WITH_SENDFILE */
-        /* FIXME with OS X deadlock partial workaround we can't use sendfile */
+#ifdef WITH_SENDFILE 
         if (!(xlate || Debug(obj) )) {
         if (!(xlate || Debug(obj) )) {
-            if (ad_readfile(ofork->of_ad, eid, dsi->socket, offset, dsi->datasize) < 0) {
+            int fd;
+                        
+            fd = ad_readfile_init(ofork->of_ad, eid, &offset, 0);
+            if (dsi_stream_read_file(dsi, fd, offset, dsi->datasize) < 0) {
                 if (errno == EINVAL || errno == ENOSYS)
                     goto afp_read_loop;
                 else {
                 if (errno == EINVAL || errno == ENOSYS)
                     goto afp_read_loop;
                 else {
index 685c548c5f8f5de0d1099da799a29db0a7be99f4..467f411808252972032c1a314cc32d05c8ee56cb 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: adouble.h,v 1.47 2009-10-21 13:28:17 didg Exp $
+ * $Id: adouble.h,v 1.48 2009-10-25 09:47:04 didg Exp $
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
  *
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
  *
@@ -543,8 +543,9 @@ extern u_int32_t ad_forcegetid (struct adouble *adp);
 #endif
 
 #ifdef WITH_SENDFILE
 #endif
 
 #ifdef WITH_SENDFILE
-extern ssize_t ad_readfile (const struct adouble *, const int,
-                                const int, off_t, const size_t);
+extern int ad_readfile_init(const struct adouble *ad, 
+                                      const int eid, off_t *off,
+                                      const int end);
 #endif
 
 #if 0
 #endif
 
 #if 0
index de7beaf82a3d52160465827f222f7bd26cc7af9d..0c40f1f17d38f5cb9d84ab6a2ab821c194b0d8d9 100644 (file)
@@ -169,6 +169,10 @@ extern size_t dsi_stream_read (DSI *, void *, const size_t);
 extern int dsi_stream_send (DSI *, void *, size_t);
 extern int dsi_stream_receive (DSI *, void *, const size_t, size_t *);
 
 extern int dsi_stream_send (DSI *, void *, size_t);
 extern int dsi_stream_receive (DSI *, void *, const size_t, size_t *);
 
+#ifdef WITH_SENDFILE
+extern ssize_t dsi_stream_read_file(DSI *, int, off_t off, const size_t len);
+#endif
+
 /* client writes -- dsi_write.c */
 extern size_t dsi_writeinit (DSI *, void *, const size_t);
 extern size_t dsi_write (DSI *, void *, const size_t);
 /* client writes -- dsi_write.c */
 extern size_t dsi_writeinit (DSI *, void *, const size_t);
 extern size_t dsi_write (DSI *, void *, const size_t);
index b4b63a94cabad5a6352c8a17c0d364c2fee05ce9..48d9934645a901ba96ac8342cc3178e4e20f8ba0 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: ad_sendfile.c,v 1.9 2008-12-03 18:35:44 didg Exp $
+ * $Id: ad_sendfile.c,v 1.10 2009-10-25 09:47:04 didg Exp $
  *
  * Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
  *
  * Copyright (c) 1999 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
@@ -43,7 +43,6 @@
 #include <errno.h>  
 
 #include <atalk/logger.h>
 #include <errno.h>  
 
 #include <atalk/logger.h>
-
 #include "ad_private.h"
 
 #if defined(LINUX_BROKEN_SENDFILE_API)
 #include "ad_private.h"
 
 #if defined(LINUX_BROKEN_SENDFILE_API)
@@ -52,8 +51,9 @@ extern int32_t sendfile (int fdout, int fdin, int32_t *offset, u_int32_t count);
 
 ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
 {
 
 ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
 {
-u_int32_t small_total = 0;
+u_int32_t small_total;
 int32_t small_offset;
 int32_t small_offset;
+int32_t nwritten;
 
     /*
      * Fix for broken Linux 2.4 systems with no working sendfile64().
 
     /*
      * Fix for broken Linux 2.4 systems with no working sendfile64().
@@ -66,22 +66,13 @@ int32_t small_offset;
          errno = ENOSYS;
          return -1;
      }
          errno = ENOSYS;
          return -1;
      }
-     small_total = (u_int32_t)count;
      small_offset = (int32_t)*offset;
      small_offset = (int32_t)*offset;
-     while (small_total) {
-         int32_t nwritten;
-         do {
-             nwritten = sendfile(tofd, fromfd, &small_offset, small_total);
-         } while (nwritten == -1 && errno == EINTR);
-         if (nwritten == -1)
-             return -1;
-         if (nwritten == 0)
-             return -1; /* I think we're at EOF here... */
-         small_total -= nwritten;
-    }
-    *offset += count;
-    return count;
+     small_total = (u_int32_t)count;
+     nwritten = sendfile(tofd, fromfd, &small_offset, small_total);
+     if (nwritten > = 0)
+         *offset += nwritten;
+     
+    return nwritten;
 }
 
 #elif defined(SENDFILE_FLAVOR_LINUX)
 }
 
 #elif defined(SENDFILE_FLAVOR_LINUX)
@@ -89,26 +80,13 @@ int32_t small_offset;
 
 ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
 {
 
 ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
 {
-size_t total=0;
-
-    total = count;
-    while (total) {
-        ssize_t nwritten;
-        do {
-            nwritten = sendfile(tofd, fromfd, offset, total);
-        } while (nwritten == -1 && errno == EINTR);
-        if (nwritten == -1)
-            return -1;
-        if (nwritten == 0)
-            return -1; /* I think we're at EOF here... */
-        total -= nwritten;
-    }
-    return count;
+    return sendfile(tofd, fromfd, offset, count);
 }
 
 
 #elif defined(SENDFILE_FLAVOR_BSD )
 /* FIXME untested */
 }
 
 
 #elif defined(SENDFILE_FLAVOR_BSD )
 /* FIXME untested */
+#error sendfile semantic broken
 #include <sys/sendfile.h>
 ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
 {
 #include <sys/sendfile.h>
 ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
 {
@@ -140,7 +118,7 @@ ssize_t sys_sendfile(int out_fd, int in_fd, off_t *_offset, size_t count)
 #endif
 
 /* ------------------------------- */
 #endif
 
 /* ------------------------------- */
-static int ad_sendfile_init(const struct adouble *ad, 
+int ad_readfile_init(const struct adouble *ad, 
                                       const int eid, off_t *off,
                                       const int end)
 {
                                       const int eid, off_t *off,
                                       const int end)
 {
@@ -150,30 +128,16 @@ static int ad_sendfile_init(const struct adouble *ad,
     *off = ad_size(ad, eid) - *off;
 
   if (eid == ADEID_DFORK) {
     *off = ad_size(ad, eid) - *off;
 
   if (eid == ADEID_DFORK) {
-    fd = ad_dfileno(ad);
+    fd = ad_data_fileno(ad);
   } else {
     *off += ad_getentryoff(ad, eid);
   } else {
     *off += ad_getentryoff(ad, eid);
-    fd = ad_hfileno(ad);
+    fd = ad_reso_fileno(ad);
   }
 
   return fd;
 }
 
 
   }
 
   return fd;
 }
 
 
-/* --------------------------------
- * read from adouble file and write to socket. sendfile doesn't change
- * the file pointer position. */
-ssize_t ad_readfile(const struct adouble *ad, const int eid, 
-                   const int sock, off_t off, const size_t len)
-{
-  off_t cc;
-  int fd;
-
-  fd = ad_sendfile_init(ad, eid, &off, 0);
-  cc = sys_sendfile(sock, fd, &off, len);
-  return cc;
-}
-
 /* ------------------------ */
 #if 0
 #ifdef HAVE_SENDFILE_WRITE
 /* ------------------------ */
 #if 0
 #ifdef HAVE_SENDFILE_WRITE
index f768e31fb6eb99523de5f2cbd70966921a7ccf8f..2bd50bee051723a3809b7a0ee763e707140bae89 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * $Id: dsi_stream.c,v 1.17 2009-10-25 06:13:11 didg Exp $
+ * $Id: dsi_stream.c,v 1.18 2009-10-25 09:47:05 didg Exp $
  *
  * Copyright (c) 1998 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
  *
  * Copyright (c) 1998 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
@@ -37,6 +37,7 @@
 
 #include <atalk/dsi.h>
 #include <netatalk/endian.h>
 
 #include <atalk/dsi.h>
 #include <netatalk/endian.h>
+#include <atalk/util.h>
 #include <sys/ioctl.h> 
 
 #define min(a,b)  ((a) < (b) ? (a) : (b))
 #include <sys/ioctl.h> 
 
 #define min(a,b)  ((a) < (b) ? (a) : (b))
@@ -191,6 +192,52 @@ ssize_t dsi_stream_write(DSI *dsi, void *data, const size_t length, int mode)
   return written;
 }
 
   return written;
 }
 
+
+/* ---------------------------------
+*/
+ssize_t dsi_stream_read_file(DSI *dsi, int fromfd, off_t offset, const size_t length)
+{
+  size_t written;
+  ssize_t len;
+
+  dsi->in_write++;
+  written = 0;
+
+  while (written < length) {
+    len = sys_sendfile(dsi->socket, fromfd, &offset, length - written);
+        
+    if (len < 0) {
+      if (errno == EINTR)
+          continue;
+      if (errno == EINVAL || errno == ENOSYS)
+          return -1;
+          
+      if (errno == EAGAIN || errno == EWOULDBLOCK) {
+          if (dsi_buffer(dsi)) {
+              /* can't go back to blocking mode, exit, the next read
+                 will return with an error and afpd will die.
+              */
+              break;
+          }
+          continue;
+      }
+      LOG(log_error, logtype_default, "dsi_stream_write: %s", strerror(errno));
+      break;
+    }
+    else if (!len) {
+        /* afpd is going to exit */
+        errno = EIO;
+        return -1; /* I think we're at EOF here... */
+    }
+    else 
+        written += len;
+  }
+
+  dsi->write_count += written;
+  dsi->in_write--;
+  return written;
+}
+
 /* ---------------------------------
 */
 static size_t from_buf(DSI *dsi, u_int8_t *buf, size_t count)
 /* ---------------------------------
 */
 static size_t from_buf(DSI *dsi, u_int8_t *buf, size_t count)