-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)
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,[
/*
- * $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.
*
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 */
goto geticon_exit;
}
}
- goto geticon_done;
+ else {
+ dsi_readdone(dsi);
+ return AFP_OK;
+ }
}
#endif
buflen = read(si.sdt_fd, rbuf, *rbuflen);
*rbuflen = buflen;
}
-
+
dsi_readdone(dsi);
return AFP_OK;
/*
- * $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.
*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 (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 {
/*
- * $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.
*
#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
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);
/*
- * $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.
#include <errno.h>
#include <atalk/logger.h>
-
#include "ad_private.h"
#if defined(LINUX_BROKEN_SENDFILE_API)
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 nwritten;
/*
* Fix for broken Linux 2.4 systems with no working sendfile64().
errno = ENOSYS;
return -1;
}
- small_total = (u_int32_t)count;
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)
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 */
+#error sendfile semantic broken
#include <sys/sendfile.h>
ssize_t sys_sendfile(int tofd, int fromfd, off_t *offset, size_t count)
{
#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)
{
*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);
- fd = ad_hfileno(ad);
+ fd = ad_reso_fileno(ad);
}
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
/*
- * $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.
#include <atalk/dsi.h>
#include <netatalk/endian.h>
+#include <atalk/util.h>
#include <sys/ioctl.h>
#define min(a,b) ((a) < (b) ? (a) : (b))
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)