diff options
author | Volker Lendecke <vl@samba.org> | 2008-12-22 22:32:12 +0100 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2008-12-29 13:24:28 +0100 |
commit | e4d28dbc040e186f453d77c7c1fb628a6cc2e3d4 (patch) | |
tree | f33ea8ab88afc8558af658edff9805721a1d2f1c /source3 | |
parent | afd70855b77aee4500b7d505419c750b6b2df38b (diff) | |
download | samba-e4d28dbc040e186f453d77c7c1fb628a6cc2e3d4.tar.gz samba-e4d28dbc040e186f453d77c7c1fb628a6cc2e3d4.tar.bz2 samba-e4d28dbc040e186f453d77c7c1fb628a6cc2e3d4.zip |
Attempt to fix bug 5953: Make cli_send_smb_direct_writeX use writev
It seems there are SMB servers around which can't cope with the write header
being sent in a packet of its own. With writev we keep the advantage of direct
writes, giving the kernel the chance to coalesce the write calls.
Diffstat (limited to 'source3')
-rw-r--r-- | source3/libsmb/clientgen.c | 40 |
1 files changed, 13 insertions, 27 deletions
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ff01b6798f..fd5627d763 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -315,7 +315,7 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli, /* First length to send is the offset to the data. */ size_t len = SVAL(cli->outbuf,smb_vwv11) + 4; size_t nwritten=0; - ssize_t ret; + struct iovec iov[2]; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) { @@ -327,33 +327,19 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli, return false; } - while (nwritten < len) { - ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); - if (ret <= 0) { - close(cli->fd); - cli->fd = -1; - cli->smb_rw_error = SMB_WRITE_ERROR; - DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", - (int)len,(int)ret, strerror(errno) )); - return false; - } - nwritten += ret; - } + iov[0].iov_base = cli->outbuf; + iov[0].iov_len = len; + iov[1].iov_base = CONST_DISCARD(char *, p); + iov[1].iov_len = extradata; - /* Now write the extra data. */ - nwritten=0; - while (nwritten < extradata) { - ret = write_socket(cli->fd,p+nwritten,extradata - nwritten); - if (ret <= 0) { - close(cli->fd); - cli->fd = -1; - cli->smb_rw_error = SMB_WRITE_ERROR; - DEBUG(0,("Error writing %d extradata " - "bytes to client. %d (%s)\n", - (int)extradata,(int)ret, strerror(errno) )); - return false; - } - nwritten += ret; + nwritten = write_data_iov(cli->fd, iov, 2); + if (nwritten < (len + extradata)) { + close(cli->fd); + cli->fd = -1; + cli->smb_rw_error = SMB_WRITE_ERROR; + DEBUG(0,("Error writing %d bytes to client. (%s)\n", + (int)(len+extradata), strerror(errno))); + return false; } /* Increment the mid so we can tell between responses. */ |