The branch, master has been updated
       via  7c5ea40 s3:smb2_read: let smb2_sendfile_send_data() behave like 
send_file_readX()
      from  fa06617 s3:winbindd: remove unused get[pw|gr]ent_initialized from 
winbindd_cli_state

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 7c5ea400ad1f280f5c338c31a0a893154340fdb3
Author: Stefan Metzmacher <[email protected]>
Date:   Thu Jul 10 21:08:06 2014 +0200

    s3:smb2_read: let smb2_sendfile_send_data() behave like send_file_readX()
    
    We now pass the header to SMB_VFS_SENDFILE(), so we have to handle that also
    in the fallback code.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10706
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    
    Autobuild-User(master): Jeremy Allison <[email protected]>
    Autobuild-Date(master): Fri Jul 11 22:57:17 CEST 2014 on sn-devel-104

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/smb2_read.c |   69 +++++++++++++++++++++++++++++++++++----------
 1 files changed, 53 insertions(+), 16 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index 05563b2..603c4a0 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -184,11 +184,13 @@ static int smb2_sendfile_send_data(struct 
smbd_smb2_read_state *state)
        uint32_t in_length = state->in_length;
        uint64_t in_offset = state->in_offset;
        files_struct *fsp = state->fsp;
+       const DATA_BLOB *hdr = state->smb2req->queue_entry.sendfile_header;
        ssize_t nread;
+       ssize_t ret;
 
        nread = SMB_VFS_SENDFILE(fsp->conn->sconn->sock,
                                 fsp,
-                                state->smb2req->queue_entry.sendfile_header,
+                                hdr,
                                 in_offset,
                                 in_length);
        DEBUG(10,("smb2_sendfile_send_data: SMB_VFS_SENDFILE returned %d on 
file %s\n",
@@ -196,11 +198,19 @@ static int smb2_sendfile_send_data(struct 
smbd_smb2_read_state *state)
                fsp_str_dbg(fsp) ));
 
        if (nread == -1) {
-               if (errno == ENOSYS || errno == EINTR) {
+               /*
+                * Returning ENOSYS means no data at all was sent.
+                  Do this as a normal read. */
+               if (errno == ENOSYS) {
+                       goto normal_read;
+               }
+
+               if (errno == EINTR) {
                        /*
-                        * Special hack for broken systems with no working
-                        * sendfile. Fake this up by doing read/write calls.
-                       */
+                        * 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.
+                        */
                        set_use_sendfile(SNUM(fsp->conn), false);
                        nread = fake_sendfile(fsp, in_offset, in_length);
                        if (nread == -1) {
@@ -231,23 +241,50 @@ static int smb2_sendfile_send_data(struct 
smbd_smb2_read_state *state)
                DEBUG(3, ("send_file_readX: sendfile sent zero bytes "
                        "falling back to the normal read: %s\n",
                        fsp_str_dbg(fsp)));
+               goto normal_read;
+       }
 
-               nread = fake_sendfile(fsp, in_offset, in_length);
-               if (nread == -1) {
-                       DEBUG(0,("smb2_sendfile_send_data: "
-                               "fake_sendfile failed for file "
-                               "%s (%s). Terminating\n",
-                               fsp_str_dbg(fsp),
-                               strerror(errno)));
-                       exit_server_cleanly("smb2_sendfile_send_data: "
-                               "fake_sendfile failed");
-               }
+       /*
+        * We got a short read
+        */
+       goto out;
+
+normal_read:
+       /* Send out the header. */
+       ret = write_data(fsp->conn->sconn->sock,
+                        (const char *)hdr->data, hdr->length);
+       if (ret != hdr->length) {
+               char addr[INET6_ADDRSTRLEN];
+               /*
+                * Try and give an error message saying what
+                * client failed.
+                */
+               DEBUG(0, ("smb2_sendfile_send_data: write_data failed "
+                         "for client %s. Error %s\n",
+                         get_peer_addr(fsp->conn->sconn->sock, addr,
+                                       sizeof(addr)),
+                         strerror(errno)));
+
+               DEBUG(0,("smb2_sendfile_send_data: write_data failed for file "
+                        "%s (%s). Terminating\n", fsp_str_dbg(fsp),
+                        strerror(errno)));
+               exit_server_cleanly("smb2_sendfile_send_data: write_data 
failed");
+       }
+       nread = fake_sendfile(fsp, in_offset, in_length);
+       if (nread == -1) {
+               DEBUG(0,("smb2_sendfile_send_data: "
+                       "fake_sendfile failed for file "
+                       "%s (%s). Terminating\n",
+                       fsp_str_dbg(fsp),
+                       strerror(errno)));
+               exit_server_cleanly("smb2_sendfile_send_data: "
+                       "fake_sendfile failed");
        }
 
   out:
 
        if (nread < in_length) {
-               sendfile_short_send(fsp, nread, 0, in_length);
+               sendfile_short_send(fsp, nread, hdr->length, in_length);
        }
 
        init_strict_lock_struct(fsp,


-- 
Samba Shared Repository

Reply via email to