r24347: fake_sendfile does not need Inbuf/Outbuf
authorVolker Lendecke <vlendec@samba.org>
Sun, 12 Aug 2007 11:22:26 +0000 (11:22 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:29:31 +0000 (12:29 -0500)
In the future, we might put the new Linux splice(2) syscall here. This
should also work for reply_write, but getting that in is a bit trickier.
We need to decide very early before fetching the whole buffer that we
have a write call.

source/smbd/reply.c

index 93e2aaf0be5191d39345104712b4dcea07f5b3a6..9119ec1e0b9cd4b6d04d4ab165c4a90c987611c8 100644 (file)
@@ -2333,9 +2333,22 @@ static void fail_readraw(void)
  Fake (read/write) sendfile. Returns -1 on read or write fail.
 ****************************************************************************/
 
-static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, size_t nread, char *buf, size_t bufsize)
+static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos,
+                            size_t nread)
 {
+       size_t bufsize;
        size_t tosend = nread;
+       char *buf;
+
+       if (nread == 0) {
+               return 0;
+       }
+
+       bufsize = MIN(nread, 65536);
+
+       if (!(buf = SMB_MALLOC_ARRAY(char, bufsize))) {
+               return -1;
+       }
 
        while (tosend > 0) {
                ssize_t ret;
@@ -2348,6 +2361,7 @@ static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, size_t nread
                }
                ret = read_file(fsp,buf,startpos,cur_read);
                if (ret == -1) {
+                       SAFE_FREE(buf);
                        return -1;
                }
 
@@ -2357,12 +2371,14 @@ static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, size_t nread
                }
 
                if (write_data(smbd_server_fd(),buf,cur_read) != cur_read) {
+                       SAFE_FREE(buf);
                        return -1;
                }
                tosend -= cur_read;
                startpos += cur_read;
        }
 
+       SAFE_FREE(buf);
        return (ssize_t)nread;
 }
 
@@ -2408,7 +2424,7 @@ void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T st
                                set_use_sendfile(SNUM(conn), False);
                                DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
 
-                               if (fake_sendfile(fsp, startpos, nread, outbuf + 4, out_buffsize - 4) == -1) {
+                               if (fake_sendfile(fsp, startpos, nread) == -1) {
                                        DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
                                                fsp->fsp_name, strerror(errno) ));
                                        exit_server_cleanly("send_file_readbraw fake_sendfile failed");
@@ -2806,9 +2822,9 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
                                /* Ensure we don't do this again. */
                                set_use_sendfile(SNUM(conn), False);
                                DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
-
-                               if ((nread = fake_sendfile(fsp, startpos, smb_maxcnt, data,
-                                                       len_outbuf - (data-outbuf))) == -1) {
+                               nread = fake_sendfile(fsp, startpos,
+                                                     smb_maxcnt);
+                               if (nread == -1) {
                                        DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
                                                fsp->fsp_name, strerror(errno) ));
                                        exit_server_cleanly("send_file_readX: fake_sendfile failed");
@@ -2844,8 +2860,8 @@ normal_read:
                                fsp->fsp_name, strerror(errno) ));
                        exit_server_cleanly("send_file_readX sendfile failed");
                }
-               if ((nread = fake_sendfile(fsp, startpos, smb_maxcnt, data,
-                                       len_outbuf - (data-outbuf))) == -1) {
+               nread = fake_sendfile(fsp, startpos, smb_maxcnt);
+               if (nread == -1) {
                        DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
                                fsp->fsp_name, strerror(errno) ));
                        exit_server_cleanly("send_file_readX: fake_sendfile failed");