From cd4ee93f8714b72f77efb5304bea694c4aef71ac Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 10 Feb 2016 23:55:11 +0100 Subject: running FreeBSD sendfile --- src/server/net.c | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/src/server/net.c b/src/server/net.c index b919d62..181e44a 100644 --- a/src/server/net.c +++ b/src/server/net.c @@ -359,29 +359,52 @@ void *net_client_handler(void *dnbd3_client) } while ( done < realBytes ) { #ifdef __linux__ - const ssize_t ret = sendfile( client->sock, image_file, &offset, realBytes - done ); -#elif defined(__FreeBSD__) - off_t sent; - int ret = sendfile( image_file, client->sock, offset, realBytes - done, NULL, &sent, 0 ); -#endif - if ( ret <= 0 ) { + const ssize_t ret = sendfile(client->sock, image_file, &offset, realBytes - done); + if (ret <= 0) { const int err = errno; - if ( lock ) pthread_mutex_unlock( &client->sendMutex ); + if (lock) pthread_mutex_unlock(&client->sendMutex); + if (ret == -1) { + if (err != EPIPE && err != ECONNRESET && err != ESHUTDOWN + && err != EAGAIN && err != EWOULDBLOCK) { + logadd(LOG_DEBUG1, "sendfile to %s failed (image to net. sent %d/%d, errno=%d)", + client->hostName, (int) done, (int) realBytes, err); + } + if (err == EBADF || err == EFAULT || err == EINVAL || err == EIO) { + logadd(LOG_INFO, "Disabling %s:%d", image->name, image->rid); + image->working = false; + } + } + goto exit_client_cleanup; + } + done += ret; +#elif defined(__FreeBSD__) + off_t sent; + int ret = sendfile( image_file, client->sock, offset, realBytes - done, NULL, &sent, 0 ); + const int err = errno; + if ( ret < 0 ) { + if (err == EAGAIN) { + done += sent; + continue; + } if ( ret == -1 ) { if ( err != EPIPE && err != ECONNRESET && err != ESHUTDOWN - && err != EAGAIN && err != EWOULDBLOCK ) { - logadd( LOG_DEBUG1, "sendfile to %s failed (image to net. sent %d/%d, errno=%d)", - client->hostName, (int)done, (int)realBytes, err ); + && err != EAGAIN && err != EWOULDBLOCK ) { + logadd( LOG_DEBUG1, "sendfile to %s failed (image to net. sent %d/%d, errno=%d)", + client->hostName, (int)done, (int)realBytes, err ); } if ( err == EBADF || err == EFAULT || err == EINVAL || err == EIO ) { - logadd( LOG_INFO, "Disabling %s:%d", image->name, image->rid ); - image->working = false; + logadd( LOG_INFO, "Disabling %s:%d", image->name, image->rid ); + image->working = false; } } goto exit_client_cleanup; + } else { + done += sent; + if (sent == 0) break; } - done += ret; +#endif } + logadd(LOG_DEBUG2, "Send %i to %s", realBytes, client->hostName); if ( request.size > (uint32_t)realBytes ) { if ( !sendPadding( client->sock, request.size - (uint32_t)realBytes ) ) { if ( lock ) pthread_mutex_unlock( &client->sendMutex ); -- cgit v1.2.3-55-g7522