summaryrefslogtreecommitdiffstats
path: root/source3
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2013-12-04 12:32:36 +0100
committerJeremy Allison <jra@samba.org>2014-03-05 13:59:20 -0800
commita6ce8001b4d022134e21cdf4c3180596a5a69101 (patch)
tree7c96d4a6be820ecd2bf1857a688380940bad0dd8 /source3
parent0ac924b2bb3c256f10cde358b95ea1d8a3833972 (diff)
downloadsamba-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.c30
-rw-r--r--source3/smbd/smb2_server.c14
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;
}