diff options
author | Stefan Metzmacher <metze@samba.org> | 2013-11-15 09:12:40 +0100 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2014-04-11 21:41:08 +0200 |
commit | 535103e7a38e175fec082a658c2b70dbdd9af33e (patch) | |
tree | f46e325ba6ccba10774534e9b22920b19134424b /source3 | |
parent | 80de72bb57520a1a14c3d3db3f31dc588d0afd64 (diff) | |
download | samba-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')
-rw-r--r-- | source3/smbd/globals.h | 1 | ||||
-rw-r--r-- | source3/smbd/smb2_server.c | 48 |
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); |