From 2fe7d5936aea2ab74bf63997212f509e4a3ccee4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 15 Dec 2008 12:06:00 +0100 Subject: Prefer network writes over reads If we really want to keep the pipe busy, we need to write everything we have as early as possible, giving the kernel the chance to get rid of the buffers quickly :-) --- source3/libsmb/async_smb.c | 65 +++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 32 deletions(-) (limited to 'source3/libsmb/async_smb.c') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index fd2fe930f8..522d73fbd9 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -955,6 +955,39 @@ static void cli_state_handler(struct event_context *event_ctx, DEBUG(11, ("cli_state_handler called with flags %d\n", flags)); + if (flags & EVENT_FD_WRITE) { + size_t to_send; + ssize_t sent; + + for (req = cli->outstanding_requests; req; req = req->next) { + to_send = smb_len(req->outbuf)+4; + if (to_send > req->sent) { + break; + } + } + + if (req == NULL) { + if (cli->fd_event != NULL) { + event_fd_set_not_writeable(cli->fd_event); + } + return; + } + + sent = sys_send(cli->fd, req->outbuf + req->sent, + to_send - req->sent, 0); + + if (sent < 0) { + status = map_nt_error_from_unix(errno); + goto sock_error; + } + + req->sent += sent; + + if (req->sent == to_send) { + return; + } + } + if (flags & EVENT_FD_READ) { int res, available; size_t old_size, new_size; @@ -1020,38 +1053,6 @@ static void cli_state_handler(struct event_context *event_ctx, } } - if (flags & EVENT_FD_WRITE) { - size_t to_send; - ssize_t sent; - - for (req = cli->outstanding_requests; req; req = req->next) { - to_send = smb_len(req->outbuf)+4; - if (to_send > req->sent) { - break; - } - } - - if (req == NULL) { - if (cli->fd_event != NULL) { - event_fd_set_not_writeable(cli->fd_event); - } - return; - } - - sent = sys_send(cli->fd, req->outbuf + req->sent, - to_send - req->sent, 0); - - if (sent < 0) { - status = map_nt_error_from_unix(errno); - goto sock_error; - } - - req->sent += sent; - - if (req->sent == to_send) { - return; - } - } return; sock_error: -- cgit From 4abdd3981e9688aaaf19173182ace7b1fdf93f6d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 19 Dec 2008 14:27:20 +0100 Subject: Pass "bytes_alignment" up through cli_request_send This parameter makes smb_spice_chain add padding before the bytes field --- source3/libsmb/async_smb.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/async_smb.c') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 522d73fbd9..21ffa94fe7 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -394,6 +394,7 @@ static struct async_req *cli_request_chain(TALLOC_CTX *mem_ctx, uint8_t smb_command, uint8_t additional_flags, uint8_t wct, const uint16_t *vwv, + size_t bytes_alignment, uint16_t num_bytes, const uint8_t *bytes) { @@ -423,7 +424,7 @@ static struct async_req *cli_request_chain(TALLOC_CTX *mem_ctx, cli_async_req_destructor); if (!smb_splice_chain(&req->outbuf, smb_command, wct, vwv, - 0, num_bytes, bytes)) { + bytes_alignment, num_bytes, bytes)) { goto fail; } @@ -569,6 +570,7 @@ void cli_chain_uncork(struct cli_state *cli) * @param[in] additional_flags open_and_x wants to add oplock header flags * @param[in] wct How many words? * @param[in] vwv The words, already in network order + * @param[in] bytes_alignment How shall we align "bytes"? * @param[in] num_bytes How many bytes? * @param[in] bytes The data the request ships * @@ -581,6 +583,7 @@ struct async_req *cli_request_send(TALLOC_CTX *mem_ctx, uint8_t smb_command, uint8_t additional_flags, uint8_t wct, const uint16_t *vwv, + size_t bytes_alignment, uint16_t num_bytes, const uint8_t *bytes) { struct async_req *result; @@ -596,7 +599,7 @@ struct async_req *cli_request_send(TALLOC_CTX *mem_ctx, } result = cli_request_chain(mem_ctx, ev, cli, smb_command, - additional_flags, wct, vwv, + additional_flags, wct, vwv, bytes_alignment, num_bytes, bytes); if (result == NULL) { -- cgit From 45ad3df1405c5d978872d6de63df5059efcc181f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 19 Dec 2008 14:28:29 +0100 Subject: Fix the padding calculation in smb_splice_chain for "bytes_padding!=0" --- source3/libsmb/async_smb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/async_smb.c') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 21ffa94fe7..24e09e0107 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -269,7 +269,7 @@ bool smb_splice_chain(char **poutbuf, uint8_t smb_command, new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2; if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) { - bytes_padding = bytes_alignment + (new_size % bytes_alignment); + bytes_padding = bytes_alignment - (new_size % bytes_alignment); } new_size += bytes_padding + num_bytes; -- cgit From 98c4055bcba17cde81345947d61fa2faae108654 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 19 Dec 2008 16:10:08 +0100 Subject: Add some comments If it takes more than 10 seconds to understand the code you've written yourself less than a year ago, it's time for comments or refactoring. I couldn't find a way to refactor that cleanly, so add comments :-) --- source3/libsmb/async_smb.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'source3/libsmb/async_smb.c') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 24e09e0107..3b7442a680 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -310,20 +310,42 @@ bool smb_splice_chain(char **poutbuf, uint8_t smb_command, ofs = old_size; + /* + * Push the chained request: + * + * wct field + */ + SCVAL(outbuf, ofs, wct); ofs += 1; + /* + * vwv array + */ + memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct); ofs += sizeof(uint16_t) * wct; + /* + * bcc (byte count) + */ + SSVAL(outbuf, ofs, num_bytes + bytes_padding); ofs += sizeof(uint16_t); + /* + * padding + */ + if (bytes_padding != 0) { memset(outbuf + ofs, 0, bytes_padding); ofs += bytes_padding; } + /* + * The bytes field + */ + memcpy(outbuf + ofs, bytes, num_bytes); return true; -- cgit From 398ef0fb855b3b2d6e55ae26304589fd89110628 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 19 Dec 2008 16:11:14 +0100 Subject: For large smbwrite&x, we need more than 64k bcc --- source3/libsmb/async_smb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/async_smb.c') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 3b7442a680..a5ce505908 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -234,7 +234,7 @@ static bool find_andx_cmd_ofs(char *buf, size_t *pofs) bool smb_splice_chain(char **poutbuf, uint8_t smb_command, uint8_t wct, const uint16_t *vwv, size_t bytes_alignment, - uint16_t num_bytes, const uint8_t *bytes) + uint32_t num_bytes, const uint8_t *bytes) { char *outbuf; size_t old_size, new_size; @@ -274,7 +274,7 @@ bool smb_splice_chain(char **poutbuf, uint8_t smb_command, new_size += bytes_padding + num_bytes; - if (new_size > 0xffff) { + if ((smb_command != SMBwriteX) && (new_size > 0xffff)) { DEBUG(1, ("splice_chain: %u bytes won't fit\n", (unsigned)new_size)); return false; @@ -417,7 +417,7 @@ static struct async_req *cli_request_chain(TALLOC_CTX *mem_ctx, uint8_t additional_flags, uint8_t wct, const uint16_t *vwv, size_t bytes_alignment, - uint16_t num_bytes, + uint32_t num_bytes, const uint8_t *bytes) { struct async_req **tmp_reqs; @@ -606,7 +606,7 @@ struct async_req *cli_request_send(TALLOC_CTX *mem_ctx, uint8_t additional_flags, uint8_t wct, const uint16_t *vwv, size_t bytes_alignment, - uint16_t num_bytes, const uint8_t *bytes) + uint32_t num_bytes, const uint8_t *bytes) { struct async_req *result; bool uncork = false; -- cgit From 1f04d07db0d53630d400ed35cecf7c66d3bb491c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 19 Dec 2008 17:44:32 +0100 Subject: Convert cli_request->outbuf to uint8_t --- source3/libsmb/async_smb.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'source3/libsmb/async_smb.c') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index a5ce505908..9ef9f9e06d 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -127,7 +127,7 @@ static char *cli_request_print(TALLOC_CTX *mem_ctx, struct async_req *req) static int cli_request_destructor(struct cli_request *req) { if (req->enc_state != NULL) { - common_free_enc_buffer(req->enc_state, req->outbuf); + common_free_enc_buffer(req->enc_state, (char *)req->outbuf); } DLIST_REMOVE(req->cli->outstanding_requests, req); if (req->cli->outstanding_requests == NULL) { @@ -187,7 +187,7 @@ static bool is_andx_req(uint8_t cmd) * to the chain. Find the offset to the place where we have to put our cmd. */ -static bool find_andx_cmd_ofs(char *buf, size_t *pofs) +static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs) { uint8_t cmd; size_t ofs; @@ -231,12 +231,12 @@ static bool find_andx_cmd_ofs(char *buf, size_t *pofs) * *poutbuf. */ -bool smb_splice_chain(char **poutbuf, uint8_t smb_command, +bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command, uint8_t wct, const uint16_t *vwv, size_t bytes_alignment, uint32_t num_bytes, const uint8_t *bytes) { - char *outbuf; + uint8_t *outbuf; size_t old_size, new_size; size_t ofs; size_t chain_padding = 0; @@ -280,7 +280,7 @@ bool smb_splice_chain(char **poutbuf, uint8_t smb_command, return false; } - outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, char, new_size); + outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size); if (outbuf == NULL) { DEBUG(0, ("talloc failed\n")); return false; @@ -295,7 +295,7 @@ bool smb_splice_chain(char **poutbuf, uint8_t smb_command, if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) { DEBUG(1, ("invalid command chain\n")); *poutbuf = TALLOC_REALLOC_ARRAY( - NULL, *poutbuf, char, old_size); + NULL, *poutbuf, uint8_t, old_size); return false; } @@ -512,11 +512,12 @@ bool cli_chain_cork(struct cli_state *cli, struct event_context *ev, if (size_hint == 0) { size_hint = 100; } - req->outbuf = talloc_array(req, char, smb_wct + size_hint); + req->outbuf = talloc_array(req, uint8_t, smb_wct + size_hint); if (req->outbuf == NULL) { goto fail; } - req->outbuf = TALLOC_REALLOC_ARRAY(NULL, req->outbuf, char, smb_wct); + req->outbuf = TALLOC_REALLOC_ARRAY(NULL, req->outbuf, uint8_t, + smb_wct); req->num_async = 0; req->async = NULL; @@ -525,7 +526,7 @@ bool cli_chain_cork(struct cli_state *cli, struct event_context *ev, req->recv_helper.fn = NULL; SSVAL(req->outbuf, smb_tid, cli->cnum); - cli_setup_packet_buf(cli, req->outbuf); + cli_setup_packet_buf(cli, (char *)req->outbuf); req->mid = cli_new_mid(cli); @@ -559,22 +560,23 @@ void cli_chain_uncork(struct cli_state *cli) cli->chain_accumulator = NULL; SSVAL(req->outbuf, smb_mid, req->mid); - smb_setlen(req->outbuf, talloc_get_size(req->outbuf) - 4); + smb_setlen((char *)req->outbuf, talloc_get_size(req->outbuf) - 4); - cli_calculate_sign_mac(cli, req->outbuf); + cli_calculate_sign_mac(cli, (char *)req->outbuf); if (cli_encryption_on(cli)) { NTSTATUS status; char *enc_buf; - status = cli_encrypt_message(cli, req->outbuf, &enc_buf); + status = cli_encrypt_message(cli, (char *)req->outbuf, + &enc_buf); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Error in encrypting client message. " "Error %s\n", nt_errstr(status))); TALLOC_FREE(req); return; } - req->outbuf = enc_buf; + req->outbuf = (uint8_t *)enc_buf; req->enc_state = cli->trans_enc_state; } -- cgit From 13eefa7c435cb5ac656f662c78260a82caf43180 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 19 Dec 2008 17:50:34 +0100 Subject: Add a doxygen comment line I forgot to merge --- source3/libsmb/async_smb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb/async_smb.c') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 9ef9f9e06d..fdcbb00206 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -401,6 +401,7 @@ static int cli_async_req_destructor(struct async_req *req) * @param[in] additional_flags open_and_x wants to add oplock header flags * @param[in] wct How many words? * @param[in] vwv The words, already in network order + * @param[in] bytes_alignment How shall we align "bytes"? * @param[in] num_bytes How many bytes? * @param[in] bytes The data the request ships * -- cgit