Author: jra
Date: 2004-12-20 22:01:18 +0000 (Mon, 20 Dec 2004)
New Revision: 4292

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=4292

Log:
Fix inspired by debug trace from Rob Foehl <[EMAIL PROTECTED]> - catch sendfile
errors correctly and return the correct values we want the caller to return (-1
meaning none in correct cases).
Jeremy.

Modified:
   trunk/source/smbd/reply.c


Changeset:
Modified: trunk/source/smbd/reply.c
===================================================================
--- trunk/source/smbd/reply.c   2004-12-20 21:14:28 UTC (rev 4291)
+++ trunk/source/smbd/reply.c   2004-12-20 22:01:18 UTC (rev 4292)
@@ -1783,6 +1783,11 @@
                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 @@
 
        }
 
+  normal_readbraw:
+
 #endif
 
        if (nread > 0) {
@@ -2157,12 +2164,18 @@
                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 @@
                                                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 @@
 
                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 @@
        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;
 }
 

Reply via email to