diff options
author | Stefan Metzmacher <metze@samba.org> | 2013-12-04 12:32:36 +0100 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2014-03-05 13:59:20 -0800 |
commit | a6ce8001b4d022134e21cdf4c3180596a5a69101 (patch) | |
tree | 7c96d4a6be820ecd2bf1857a688380940bad0dd8 /source3 | |
parent | 0ac924b2bb3c256f10cde358b95ea1d8a3833972 (diff) | |
download | samba-a6ce8001b4d022134e21cdf4c3180596a5a69101.tar.gz samba-a6ce8001b4d022134e21cdf4c3180596a5a69101.tar.xz samba-a6ce8001b4d022134e21cdf4c3180596a5a69101.zip |
s3:smb2_read: avoid 2 talloc* calls when using sendfile()
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3')
-rw-r--r-- | source3/smbd/smb2_read.c | 30 | ||||
-rw-r--r-- | source3/smbd/smb2_server.c | 14 |
2 files changed, 29 insertions, 15 deletions
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c index 6478326ac0..474eaeae8a 100644 --- a/source3/smbd/smb2_read.c +++ b/source3/smbd/smb2_read.c @@ -167,10 +167,16 @@ struct smbd_smb2_read_state { uint64_t in_offset; uint32_t in_minimum; DATA_BLOB out_headers; + uint8_t _out_hdr_buf[NBT_HDR_SIZE + SMB2_HDR_BODY + 0x10]; DATA_BLOB out_data; uint32_t out_remaining; }; +static int smb2_smb2_read_state_deny_destructor(struct smbd_smb2_read_state *state) +{ + return -1; +} + /* struct smbd_smb2_read_state destructor. Send the SMB2_READ data. */ static int smb2_sendfile_send_data(struct smbd_smb2_read_state *state) { @@ -258,7 +264,6 @@ static int smb2_sendfile_send_data(struct smbd_smb2_read_state *state) static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req, struct smbd_smb2_read_state *state) { - struct smbd_smb2_read_state *state_copy = NULL; files_struct *fsp = state->fsp; /* @@ -293,16 +298,8 @@ static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req, state->out_data.length = state->in_length; state->out_remaining = 0; - /* Make a copy of state attached to the smb2req. Attach - the destructor here as this will trigger the sendfile - call when the request is destroyed. */ - state_copy = talloc(smb2req, struct smbd_smb2_read_state); - if (!state_copy) { - return NT_STATUS_NO_MEMORY; - } - *state_copy = *state; - talloc_set_destructor(state_copy, smb2_sendfile_send_data); - state->smb2req->queue_entry.sendfile_header = &state_copy->out_headers; + state->out_headers = data_blob_const(state->_out_hdr_buf, + sizeof(state->_out_hdr_buf)); return NT_STATUS_OK; } @@ -582,6 +579,15 @@ static NTSTATUS smbd_smb2_read_recv(struct tevent_req *req, talloc_steal(mem_ctx, out_data->data); *out_remaining = state->out_remaining; - tevent_req_received(req); + if (state->out_headers.length > 0) { + talloc_steal(mem_ctx, state); + talloc_set_destructor(state, smb2_smb2_read_state_deny_destructor); + tevent_req_received(req); + state->smb2req->queue_entry.sendfile_header = &state->out_headers; + talloc_set_destructor(state, smb2_sendfile_send_data); + } else { + tevent_req_received(req); + } + return NT_STATUS_OK; } diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index dea3915d96..b805c1a390 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -3035,9 +3035,13 @@ static NTSTATUS smbd_smb2_flush_send_queue(struct smbd_server_connection *sconn) size += e->vector[i].iov_len; } - buf = talloc_array(e->mem_ctx, uint8_t, size); - if (buf == NULL) { - return NT_STATUS_NO_MEMORY; + if (size <= e->sendfile_header->length) { + buf = e->sendfile_header->data; + } else { + buf = talloc_array(e->mem_ctx, uint8_t, size); + if (buf == NULL) { + return NT_STATUS_NO_MEMORY; + } } size = 0; @@ -3054,6 +3058,10 @@ static NTSTATUS smbd_smb2_flush_send_queue(struct smbd_server_connection *sconn) sconn->smb2.send_queue_len--; DLIST_REMOVE(sconn->smb2.send_queue, e); + /* + * This triggers the sendfile path via + * the destructor. + */ talloc_free(e->mem_ctx); continue; } |