diff options
author | Stefan Metzmacher <metze@samba.org> | 2013-11-19 07:42:57 +0100 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2014-03-05 13:59:20 -0800 |
commit | 66877dfaa59561145eba6233dc1f43c282d8cd08 (patch) | |
tree | 3596c9dfa3d099fe64eda74c15f4e765a8c37e63 /source3/smbd | |
parent | 032621d5bf842e60dc9cd1cd0d3acc90482462a6 (diff) | |
download | samba-66877dfaa59561145eba6233dc1f43c282d8cd08.tar.gz samba-66877dfaa59561145eba6233dc1f43c282d8cd08.tar.xz samba-66877dfaa59561145eba6233dc1f43c282d8cd08.zip |
s3:smb2_server: optimize req->in.vector allocation
We can avoid a talloc_zero_array() call in the
common case (without compound requests) and use a
preallocated array instead.
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.h | 1 | ||||
-rw-r--r-- | source3/smbd/smb2_server.c | 43 |
2 files changed, 31 insertions, 13 deletions
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index bae3ed03ae2..2b7fc7ec51c 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -586,6 +586,7 @@ struct smbd_smb2_request { */ struct iovec *vector; int vector_count; + struct iovec _vector[1 + SMBD_SMB2_NUM_IOV_PER_REQ]; } in; struct { /* the NBT header is not allocated */ diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 5e6bfd95cac..192e99c8147 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -297,10 +297,11 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *conn, NTTIME now, uint8_t *buf, size_t buflen, - TALLOC_CTX *mem_ctx, + struct smbd_smb2_request *req, struct iovec **piov, int *pnum_iov) { + TALLOC_CTX *mem_ctx = req; struct iovec *iov; int num_iov = 1; size_t taken = 0; @@ -312,10 +313,7 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *conn, /* * Note: index '0' is reserved for the transport protocol */ - iov = talloc_zero_array(mem_ctx, struct iovec, num_iov); - if (iov == NULL) { - return NT_STATUS_NO_MEMORY; - } + iov = req->in._vector; while (taken < buflen) { size_t len = buflen - taken; @@ -327,7 +325,6 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *conn, uint8_t *body = NULL; uint32_t dyn_size; uint8_t *dyn = NULL; - struct iovec *iov_tmp; if (verified_buflen > taken) { len = verified_buflen - taken; @@ -458,13 +455,31 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *conn, dyn = body + body_size; dyn_size = full_size - (SMB2_HDR_BODY + body_size); - iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec, - num_iov + SMBD_SMB2_NUM_IOV_PER_REQ); - if (iov_tmp == NULL) { - TALLOC_FREE(iov); - return NT_STATUS_NO_MEMORY; + if (num_iov >= ARRAY_SIZE(req->in._vector)) { + struct iovec *iov_tmp = NULL; + struct iovec *iov_alloc = NULL; + + if (iov != req->in._vector) { + iov_alloc = iov; + } + + iov_tmp = talloc_realloc(mem_ctx, iov_alloc, + struct iovec, + num_iov + + SMBD_SMB2_NUM_IOV_PER_REQ); + if (iov_tmp == NULL) { + TALLOC_FREE(iov_alloc); + return NT_STATUS_NO_MEMORY; + } + + if (iov_alloc == NULL) { + memcpy(iov_tmp, + req->in._vector, + sizeof(req->in._vector)); + } + + iov = iov_tmp; } - iov = iov_tmp; cur = &iov[num_iov]; num_iov += SMBD_SMB2_NUM_IOV_PER_REQ; @@ -485,7 +500,9 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *conn, return NT_STATUS_OK; inval: - TALLOC_FREE(iov); + if (iov != req->in._vector) { + TALLOC_FREE(iov); + } return NT_STATUS_INVALID_PARAMETER; } |