summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2008-05-06 15:44:39 -0700
committerJeremy Allison <jra@samba.org>2008-05-06 15:44:39 -0700
commit82572cfd4370fbcfbe35f1d5f11fb05fc732cba2 (patch)
treeae63910030dbea4c1f0f5c6ea11cbc6d146fd8ae /source3/lib
parent5621ce6fb45a85e5f381286ef307e02ed8178c7f (diff)
downloadsamba-82572cfd4370fbcfbe35f1d5f11fb05fc732cba2.tar.gz
samba-82572cfd4370fbcfbe35f1d5f11fb05fc732cba2.tar.bz2
samba-82572cfd4370fbcfbe35f1d5f11fb05fc732cba2.zip
Enable tests for splice on Linux. Add a static (vl, I hate this)
so we can detect broken Linux recvfile splice and correctly fall back. Jeremy. (This used to be commit ec2d301a7aac173aba41dd2074037f27d05095ce)
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/recvfile.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/source3/lib/recvfile.c b/source3/lib/recvfile.c
index f9788fdefb..6e20933350 100644
--- a/source3/lib/recvfile.c
+++ b/source3/lib/recvfile.c
@@ -124,7 +124,7 @@ static ssize_t default_sys_recvfile(int fromfd,
return (ssize_t)total_written;
}
-#if defined(HAVE_SPLICE_SYSCALL)
+#if defined(HAVE_LINUX_SPLICE)
/*
* Try and use the Linux system call to do this.
@@ -134,17 +134,33 @@ static ssize_t default_sys_recvfile(int fromfd,
* from the network in the case of return != -1.
*/
+
ssize_t sys_recvfile(int fromfd,
int tofd,
SMB_OFF_T offset,
size_t count)
{
+ static bool try_splice_call = true;
size_t total_written = 0;
if (count == 0) {
return 0;
}
+ /*
+ * Older Linux kernels have splice for sendfile,
+ * but it fails for recvfile. Ensure we only try
+ * this once and always fall back to the userspace
+ * implementation if recvfile splice fails. JRA.
+ */
+
+ if (!try_splice_call) {
+ return default_sys_recvfile(fromfd,
+ tofd,
+ offset,
+ count);
+ }
+
while (total_written < count) {
ssize_t ret = splice(fromfd,
NULL,
@@ -155,7 +171,8 @@ ssize_t sys_recvfile(int fromfd,
if (ret == -1) {
if (errno != EINTR) {
if (total_written == 0 &&
- errno == EBADF || errno == EINVAL) {
+ (errno == EBADF || errno == EINVAL)) {
+ try_splice_call = false;
return default_sys_recvfile(fromfd,
tofd,
offset,