summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2004-12-20 22:01:42 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:53:42 -0500
commit50f3d8f249401f7c142ca785ef0f20585a38d3a3 (patch)
treec816fd0042f5695b69216a20d9373a04dc2b126c /source3
parentb46913fb95d59f3ec8e7e71da758cd16cda05f2c (diff)
downloadsamba-50f3d8f249401f7c142ca785ef0f20585a38d3a3.tar.gz
samba-50f3d8f249401f7c142ca785ef0f20585a38d3a3.tar.bz2
samba-50f3d8f249401f7c142ca785ef0f20585a38d3a3.zip
r4293: Fix inspired by debug trace from Rob Foehl <rwf@loonybin.net> - catch sendfile
errors correctly and return the correct values we want the caller to return (-1 meaning none in correct cases). Jeremy. (This used to be commit 139c1c3488237d710ceda394c028b8dc9007bff1)
Diffstat (limited to 'source3')
-rw-r--r--source3/smbd/reply.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 22cbf45e21..c5ed0eb8ba 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1783,6 +1783,11 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
header.free = NULL;
if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, nread) == -1) {
+ /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
+ if (errno == ENOSYS) {
+ goto normal_readbraw;
+ }
+
/*
* Special hack for broken Linux with no working sendfile. If we
* return EINTR we sent the header but not the rest of the data.
@@ -1808,6 +1813,8 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
}
+ normal_readbraw:
+
#endif
if (nread > 0) {
@@ -2157,12 +2164,18 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
header.length = data - outbuf;
header.free = NULL;
- if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt) == -1) {
+ if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fd, &header, startpos, smb_maxcnt)) == -1) {
+ /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
+ if (errno == ENOSYS) {
+ goto normal_read;
+ }
+
/*
* Special hack for broken Linux with no working sendfile. If we
* return EINTR we sent the header but not the rest of the data.
* Fake this up by doing read/write calls.
*/
+
if (errno == EINTR) {
/* Ensure we don't do this again. */
set_use_sendfile(SNUM(conn), False);
@@ -2174,7 +2187,10 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
fsp->fsp_name, strerror(errno) ));
exit_server("send_file_readX: fake_sendfile failed");
}
- return nread;
+ DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
+ fsp->fnum, (int)smb_maxcnt, (int)(nread + (data - outbuf)) ) );
+ /* Returning -1 here means successful sendfile. */
+ return -1;
}
DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
@@ -2184,6 +2200,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
+ /* Returning -1 here means successful sendfile. */
return -1;
}
@@ -2208,6 +2225,7 @@ int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length
DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
+ /* Returning the number of bytes we want to send back - including header. */
return outsize;
}