summaryrefslogtreecommitdiffstats
path: root/source3/smbd
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2013-11-15 09:12:40 +0100
committerJeremy Allison <jra@samba.org>2014-04-11 21:41:08 +0200
commit535103e7a38e175fec082a658c2b70dbdd9af33e (patch)
treef46e325ba6ccba10774534e9b22920b19134424b /source3/smbd
parent80de72bb57520a1a14c3d3db3f31dc588d0afd64 (diff)
downloadsamba-535103e7a38e175fec082a658c2b70dbdd9af33e.tar.gz
samba-535103e7a38e175fec082a658c2b70dbdd9af33e.tar.xz
samba-535103e7a38e175fec082a658c2b70dbdd9af33e.zip
s3:smb2_server: only allocate the required buffer in the smb2 recvfile() code path
This way the buffer will likely be allocated within the existing talloc_pool, which avoids one malloc() per request. Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/globals.h1
-rw-r--r--source3/smbd/smb2_server.c48
2 files changed, 30 insertions, 19 deletions
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 3baa048c0de..cd99fe72ca1 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -768,6 +768,7 @@ struct smbd_server_connection {
struct iovec vector;
bool doing_receivefile;
size_t min_recv_size;
+ size_t pktfull;
size_t pktlen;
uint8_t *pktbuf;
} request_read_state;
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 0e42b7fdf71..4f6967968c4 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -2924,8 +2924,7 @@ static bool is_smb2_recvfile_write(struct smbd_smb2_request_read_state *state)
}
DEBUG(10,("Doing recvfile write len = %u\n",
- (unsigned int)(state->pktlen -
- SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN)));
+ (unsigned int)(state->pktfull - state->pktlen)));
return true;
}
@@ -3263,10 +3262,21 @@ again:
* Read the rest of the data.
*/
state->doing_receivefile = false;
+
+ state->pktbuf = talloc_realloc(state->req,
+ state->pktbuf,
+ uint8_t,
+ state->pktfull);
+ if (state->pktbuf == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
state->vector.iov_base = (void *)(state->pktbuf +
- SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN);
- state->vector.iov_len = (state->pktlen -
- SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN);
+ state->pktlen);
+ state->vector.iov_len = (state->pktfull -
+ state->pktlen);
+
+ state->pktlen = state->pktfull;
goto again;
}
@@ -3283,24 +3293,17 @@ again:
if (state->hdr.nbt[0] != 0x00) {
state->min_recv_size = 0;
}
- state->pktlen = smb2_len(state->hdr.nbt);
- if (state->pktlen == 0) {
+ state->pktfull = smb2_len(state->hdr.nbt);
+ if (state->pktfull == 0) {
goto got_full;
}
- state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
- if (state->pktbuf == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
-
- state->vector.iov_base = (void *)state->pktbuf;
-
if (state->min_recv_size != 0) {
min_recvfile_size = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
min_recvfile_size += state->min_recv_size;
}
- if (state->pktlen > min_recvfile_size) {
+ if (state->pktfull > min_recvfile_size) {
/*
* Might be a receivefile write. Read the SMB2 HEADER +
* SMB2_WRITE header first. Set 'doing_receivefile'
@@ -3309,12 +3312,20 @@ again:
* not suitable then we'll just read the rest of the data
* the next time this function is called.
*/
- state->vector.iov_len = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
+ state->pktlen = SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
state->doing_receivefile = true;
} else {
- state->vector.iov_len = state->pktlen;
+ state->pktlen = state->pktfull;
}
+ state->pktbuf = talloc_array(state->req, uint8_t, state->pktlen);
+ if (state->pktbuf == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ state->vector.iov_base = (void *)state->pktbuf;
+ state->vector.iov_len = state->pktlen;
+
goto again;
got_full:
@@ -3353,8 +3364,7 @@ got_full:
if (req->smb1req == NULL) {
return NT_STATUS_NO_MEMORY;
}
- req->smb1req->unread_bytes =
- state->pktlen - SMBD_SMB2_SHORT_RECEIVEFILE_WRITE_LEN;
+ req->smb1req->unread_bytes = state->pktfull - state->pktlen;
}
ZERO_STRUCTP(state);