The branch, master has been updated
       via  9869358 s3:smb2_server: avoid talloc_zero_array() in 
smbd_smb2_request_setup_out()
       via  cf77f16 s3:smb2_server: don't assume that req->out.vector is always 
a valid talloc pointer
       via  2edc730 s3:smb2_server: avoid talloc_zero_array() in 
smbd_smb2_request_error_ex()
       via  adaf517 s3:smb2_server: optimize smbd_smb2_generate_outbody() for 
the common case
       via  d307953 s3:smb2_write: make use of smbd_smb2_generate_outbody()
       via  ec8dedb s3:smb2_tcon: make use of smbd_smb2_generate_outbody()
       via  27222bb s3:smb2_setinfo: make use of smbd_smb2_generate_outbody()
       via  39832ff s3:smb2_sesssetup: make use of smbd_smb2_generate_outbody()
       via  c099797 s3:smb2_read: make use of smbd_smb2_generate_outbody()
       via  b065578 s3:smb2_notify: make use of smbd_smb2_generate_outbody()
       via  59c185b s3:smb2_negprot: make use of smbd_smb2_generate_outbody()
       via  aa70bf5 s3:smb2_lock: make use of smbd_smb2_generate_outbody()
       via  2ddfe40 s3:smb2_keepalive: make use of smbd_smb2_generate_outbody()
       via  a6ee7ce s3:smb2_ioctl: make use of smbd_smb2_generate_outbody()
       via  a021a25 s3:smb2_getinfo: make use of smbd_smb2_generate_outbody()
       via  46840db s3:smb2_flush: make use of smbd_smb2_generate_outbody()
       via  208046b s3:smb2_find: make use of smbd_smb2_generate_outbody()
       via  2c91f05 s3:smb2_create: make use of smbd_smb2_generate_outbody()
       via  2ecd5c9 s3:smb2_close: make use of smbd_smb2_generate_outbody()
       via  c09292e s3:smb2_break: make use of smbd_smb2_generate_outbody()
       via  fd4c82f s3:smb2_server: add smbd_smb2_generate_outbody() helper
       via  a6ce800 s3:smb2_read: avoid 2 talloc* calls when using sendfile()
       via  0ac924b s3:smb2_server: avoid a call to data_blob_clear_free() if 
not needed
       via  ec498a2 s3:smb2_server: optimize smbd_smb2_request_setup_out()
       via  66877df s3:smb2_server: optimize req->in.vector allocation
      from  032621d s3:smbd: s/BUFFER_SIZE/LARGE_WRITEX_BUFFER_SIZE

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 986935854f6ef4638d544054b9ed79f1d407bbf9
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 15:32:45 2013 +0100

    s3:smb2_server: avoid talloc_zero_array() in smbd_smb2_request_setup_out()
    
    In the common case with just one request, we can use a preallocated
    req->out.vector.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>
    
    Autobuild-User(master): Jeremy Allison <j...@samba.org>
    Autobuild-Date(master): Thu Mar  6 00:59:29 CET 2014 on sn-devel-104

commit cf77f16e3aa60258813b030f8a7f2e0cdd576368
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 15:28:11 2013 +0100

    s3:smb2_server: don't assume that req->out.vector is always a valid talloc 
pointer
    
    We use 'req' instead as it has the same lifetime.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 2edc7308d6185d724f38e602520617121ef57672
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 15:24:29 2013 +0100

    s3:smb2_server: avoid talloc_zero_array() in smbd_smb2_request_error_ex()
    
    It is only important that the content of info->data stays alive
    for the lifetime of the request, but the DATA_BLOB structure itself
    can be on the stack, while passing it as 'dyn' to 
smbd_smb2_request_done_ex().
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit adaf517c87db22cb5b74906d43cfbae74a07130c
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 15:05:34 2013 +0100

    s3:smb2_server: optimize smbd_smb2_generate_outbody() for the common case
    
    Use a preallocated buffer for the first response in the compound chain.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit d307953e08038cf4ba0367a85296d9f3b11d51d7
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_write: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit ec8dedb50f8be4c79b1018700b30f035a39650d3
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_tcon: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 27222bb4f47d72e2759aca83e471d50db6321a26
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_setinfo: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 39832ff588e4291df13307ab807130123768d3d6
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_sesssetup: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit c099797238e0671e2c816f9a71b06859595264aa
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_read: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit b065578320b51c8994ff01e79306640cabed1c6f
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_notify: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 59c185bf549b359728183c8e61c165823f6112ef
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_negprot: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit aa70bf5fdcfecf6966e7808d1837bbe134042d5b
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_lock: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 2ddfe40425366dce59b9a23d65044c6a6f93ec81
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_keepalive: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit a6ee7ce31a864db5a46bcf78d190f8955b95415c
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_ioctl: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit a021a25104aa570efd8b69920b26fc2dcc6b5c04
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_getinfo: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 46840db4160bfb4a908c08b065cd9130d63e2d86
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_flush: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 208046b2eb83ca4b5c30b9fa3da69efae439fee3
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_find: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 2c91f0506bca7936c4e25a8151a6b519c92faae9
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_create: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 2ecd5c9693a98b6baefabd915a4a44e8ac3fad37
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_close: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit c09292e20d8f1a6da6d5b56a1155abce4e02acf1
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 14:59:07 2013 +0100

    s3:smb2_break: make use of smbd_smb2_generate_outbody()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit fd4c82f6f50ebe02613c498c4f0070569e9ba10c
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 12:52:21 2013 +0100

    s3:smb2_server: add smbd_smb2_generate_outbody() helper
    
    We can add optimization there later.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit a6ce8001b4d022134e21cdf4c3180596a5a69101
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Dec 4 12:32:36 2013 +0100

    s3:smb2_read: avoid 2 talloc* calls when using sendfile()
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 0ac924b2bb3c256f10cde358b95ea1d8a3833972
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Nov 20 09:56:48 2013 +0100

    s3:smb2_server: avoid a call to data_blob_clear_free() if not needed
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit ec498a2414d96567bfed26f35b60ebe1ac40c68b
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Nov 20 09:56:19 2013 +0100

    s3:smb2_server: optimize smbd_smb2_request_setup_out()
    
    We can use a preallocated buffer for the possible error
    response of the first response in the compound chain.
    
    This avoids a talloc_array_zero() call for the common case.
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

commit 66877dfaa59561145eba6233dc1f43c282d8cd08
Author: Stefan Metzmacher <me...@samba.org>
Date:   Tue Nov 19 07:42:57 2013 +0100

    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 <me...@samba.org>
    Reviewed-by: Jeremy Allison <j...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/globals.h        |    7 ++
 source3/smbd/smb2_break.c     |    2 +-
 source3/smbd/smb2_close.c     |    2 +-
 source3/smbd/smb2_create.c    |    2 +-
 source3/smbd/smb2_find.c      |    2 +-
 source3/smbd/smb2_flush.c     |    2 +-
 source3/smbd/smb2_getinfo.c   |    2 +-
 source3/smbd/smb2_ioctl.c     |    2 +-
 source3/smbd/smb2_keepalive.c |    2 +-
 source3/smbd/smb2_lock.c      |    2 +-
 source3/smbd/smb2_negprot.c   |    2 +-
 source3/smbd/smb2_notify.c    |    2 +-
 source3/smbd/smb2_read.c      |   32 ++++++----
 source3/smbd/smb2_server.c    |  133 ++++++++++++++++++++++++++++------------
 source3/smbd/smb2_sesssetup.c |    4 +-
 source3/smbd/smb2_setinfo.c   |    2 +-
 source3/smbd/smb2_tcon.c      |    4 +-
 source3/smbd/smb2_write.c     |    2 +-
 18 files changed, 136 insertions(+), 70 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index bae3ed0..3baa048 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -225,6 +225,8 @@ void reply_smb20ff(struct smb_request *req, uint16_t 
choice);
 void smbd_smb2_first_negprot(struct smbd_server_connection *sconn,
                             uint8_t *inbuf, size_t size);
 
+DATA_BLOB smbd_smb2_generate_outbody(struct smbd_smb2_request *req, size_t 
size);
+
 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
                                    NTSTATUS status,
                                    DATA_BLOB *info,
@@ -586,6 +588,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 */
@@ -610,6 +613,10 @@ struct smbd_smb2_request {
                 */
                struct iovec *vector;
                int vector_count;
+               struct iovec _vector[1 + SMBD_SMB2_NUM_IOV_PER_REQ];
+#define OUTVEC_ALLOC_SIZE (SMB2_HDR_BODY + 9)
+               uint8_t _hdr[OUTVEC_ALLOC_SIZE];
+               uint8_t _body[0x58];
        } out;
 };
 
diff --git a/source3/smbd/smb2_break.c b/source3/smbd/smb2_break.c
index 945faa1..6446b79 100644
--- a/source3/smbd/smb2_break.c
+++ b/source3/smbd/smb2_break.c
@@ -106,7 +106,7 @@ static void smbd_smb2_request_oplock_break_done(struct 
tevent_req *subreq)
        in_file_id_persistent   = BVAL(inbody, 0x08);
        in_file_id_volatile     = BVAL(inbody, 0x10);
 
-       outbody = data_blob_talloc(req->out.vector, NULL, 0x18);
+       outbody = smbd_smb2_generate_outbody(req, 0x18);
        if (outbody.data == NULL) {
                error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
                if (!NT_STATUS_IS_OK(error)) {
diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c
index dce8cac..3712ffe 100644
--- a/source3/smbd/smb2_close.c
+++ b/source3/smbd/smb2_close.c
@@ -114,7 +114,7 @@ static void smbd_smb2_request_close_done(struct tevent_req 
*subreq)
                return;
        }
 
-       outbody = data_blob_talloc(req->out.vector, NULL, 0x3C);
+       outbody = smbd_smb2_generate_outbody(req, 0x3C);
        if (outbody.data == NULL) {
                error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
                if (!NT_STATUS_IS_OK(error)) {
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index f2fec08..52ed171 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -318,7 +318,7 @@ static void smbd_smb2_request_create_done(struct tevent_req 
*tsubreq)
                out_context_buffer_offset = SMB2_HDR_BODY + 0x58;
        }
 
-       outbody = data_blob_talloc(smb2req->out.vector, NULL, 0x58);
+       outbody = smbd_smb2_generate_outbody(smb2req, 0x58);
        if (outbody.data == NULL) {
                error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
                if (!NT_STATUS_IS_OK(error)) {
diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c
index 46d0aa4..3f779b8 100644
--- a/source3/smbd/smb2_find.c
+++ b/source3/smbd/smb2_find.c
@@ -162,7 +162,7 @@ static void smbd_smb2_request_find_done(struct tevent_req 
*subreq)
 
        out_output_buffer_offset = SMB2_HDR_BODY + 0x08;
 
-       outbody = data_blob_talloc(req->out.vector, NULL, 0x08);
+       outbody = smbd_smb2_generate_outbody(req, 0x08);
        if (outbody.data == NULL) {
                error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
                if (!NT_STATUS_IS_OK(error)) {
diff --git a/source3/smbd/smb2_flush.c b/source3/smbd/smb2_flush.c
index 00a7158..0d4c1a5 100644
--- a/source3/smbd/smb2_flush.c
+++ b/source3/smbd/smb2_flush.c
@@ -84,7 +84,7 @@ static void smbd_smb2_request_flush_done(struct tevent_req 
*subreq)
                return;
        }
 
-       outbody = data_blob_talloc(req->out.vector, NULL, 0x04);
+       outbody = smbd_smb2_generate_outbody(req, 0x04);
        if (outbody.data == NULL) {
                error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
                if (!NT_STATUS_IS_OK(error)) {
diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c
index 449aeb3..ec6181a 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -178,7 +178,7 @@ static void smbd_smb2_request_getinfo_done(struct 
tevent_req *subreq)
 
        out_output_buffer_offset = SMB2_HDR_BODY + 0x08;
 
-       outbody = data_blob_talloc(req->out.vector, NULL, 0x08);
+       outbody = smbd_smb2_generate_outbody(req, 0x08);
        if (outbody.data == NULL) {
                error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
                if (!NT_STATUS_IS_OK(error)) {
diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c
index be2a798..6a19fcb 100644
--- a/source3/smbd/smb2_ioctl.c
+++ b/source3/smbd/smb2_ioctl.c
@@ -318,7 +318,7 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req 
*subreq)
        out_input_offset = SMB2_HDR_BODY + 0x30;
        out_output_offset = SMB2_HDR_BODY + 0x30;
 
-       outbody = data_blob_talloc(req->out.vector, NULL, 0x30);
+       outbody = smbd_smb2_generate_outbody(req, 0x30);
        if (outbody.data == NULL) {
                error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
                if (!NT_STATUS_IS_OK(error)) {
diff --git a/source3/smbd/smb2_keepalive.c b/source3/smbd/smb2_keepalive.c
index 24a4f8e..b16ff6b 100644
--- a/source3/smbd/smb2_keepalive.c
+++ b/source3/smbd/smb2_keepalive.c
@@ -35,7 +35,7 @@ NTSTATUS smbd_smb2_request_process_keepalive(struct 
smbd_smb2_request *req)
 
        /* TODO: update some time stamps */
 
-       outbody = data_blob_talloc(req->out.vector, NULL, 0x04);
+       outbody = smbd_smb2_generate_outbody(req, 0x04);
        if (outbody.data == NULL) {
                return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
        }
diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c
index 671cd6f..4af3d61 100644
--- a/source3/smbd/smb2_lock.c
+++ b/source3/smbd/smb2_lock.c
@@ -146,7 +146,7 @@ static void smbd_smb2_request_lock_done(struct tevent_req 
*subreq)
                return;
        }
 
-       outbody = data_blob_talloc(smb2req->out.vector, NULL, 0x04);
+       outbody = smbd_smb2_generate_outbody(smb2req, 0x04);
        if (outbody.data == NULL) {
                error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY);
                if (!NT_STATUS_IS_OK(error)) {
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index b1e71e6..6643464 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -320,7 +320,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct 
smbd_smb2_request *req)
                return smbd_smb2_request_error(req, status);
        }
 
-       outbody = data_blob_talloc(req->out.vector, NULL, 0x40);
+       outbody = smbd_smb2_generate_outbody(req, 0x40);
        if (outbody.data == NULL) {
                return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
        }
diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c
index 228346e..7351d9f 100644
--- a/source3/smbd/smb2_notify.c
+++ b/source3/smbd/smb2_notify.c
@@ -130,7 +130,7 @@ static void smbd_smb2_request_notify_done(struct tevent_req 
*subreq)
 
        out_output_buffer_offset = SMB2_HDR_BODY + 0x08;
 
-       outbody = data_blob_talloc(req->out.vector, NULL, 0x08);
+       outbody = smbd_smb2_generate_outbody(req, 0x08);
        if (outbody.data == NULL) {
                error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
                if (!NT_STATUS_IS_OK(error)) {
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index 6478326..05563b2 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -128,7 +128,7 @@ static void smbd_smb2_request_read_done(struct tevent_req 
*subreq)
 
        out_data_offset = SMB2_HDR_BODY + 0x10;
 
-       outbody = data_blob_talloc(req->out.vector, NULL, 0x10);
+       outbody = smbd_smb2_generate_outbody(req, 0x10);
        if (outbody.data == NULL) {
                error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
                if (!NT_STATUS_IS_OK(error)) {
@@ -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 5e6bfd9..3c46efd 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -37,8 +37,6 @@ static void smbd_smb2_connection_handler(struct 
tevent_context *ev,
 static NTSTATUS smbd_smb2_io_handler(struct smbd_server_connection *sconn,
                                     uint16_t fde_flags);
 
-#define OUTVEC_ALLOC_SIZE (SMB2_HDR_BODY + 9)
-
 static const struct smbd_smb2_dispatch_table {
        uint16_t opcode;
        const char *name;
@@ -255,8 +253,12 @@ static void smb2_setup_nbt_length(struct iovec *vector, 
int count)
 
 static int smbd_smb2_request_destructor(struct smbd_smb2_request *req)
 {
-       data_blob_clear_free(&req->first_key);
-       data_blob_clear_free(&req->last_key);
+       if (req->first_key.length > 0) {
+               data_blob_clear_free(&req->first_key);
+       }
+       if (req->last_key.length > 0) {
+               data_blob_clear_free(&req->last_key);
+       }
        return 0;
 }
 
@@ -297,10 +299,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 +315,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 +327,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 +457,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 +502,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;
 }
 
@@ -901,16 +920,34 @@ static void smb2_calculate_credits(const struct 
smbd_smb2_request *inreq,
        }
 }
 
+DATA_BLOB smbd_smb2_generate_outbody(struct smbd_smb2_request *req, size_t 
size)
+{
+       if (req->current_idx <= 1) {
+               if (size <= sizeof(req->out._body)) {
+                       return data_blob_const(req->out._body, size);
+               }
+       }
+
+       return data_blob_talloc(req, NULL, size);
+}
+
 static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
 {
+       TALLOC_CTX *mem_ctx;
        struct iovec *vector;
        int count;
        int idx;
 
        count = req->in.vector_count;
-       vector = talloc_zero_array(req, struct iovec, count);
-       if (vector == NULL) {
-               return NT_STATUS_NO_MEMORY;
+       if (count <= ARRAY_SIZE(req->out._vector)) {
+               mem_ctx = req;
+               vector = req->out._vector;
+       } else {
+               vector = talloc_zero_array(req, struct iovec, count);
+               if (vector == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               mem_ctx = vector;
        }
 
        vector[0].iov_base      = req->out.nbt_hdr;
@@ -931,10 +968,14 @@ static NTSTATUS smbd_smb2_request_setup_out(struct 
smbd_smb2_request *req)
                        next_command_ofs = SMB2_HDR_BODY + 9;
                }
 
-               outhdr = talloc_zero_array(vector, uint8_t,
-                                     OUTVEC_ALLOC_SIZE);
-               if (outhdr == NULL) {
-                       return NT_STATUS_NO_MEMORY;
+               if (idx == 1) {
+                       outhdr = req->out._hdr;
+               } else {
+                       outhdr = talloc_zero_array(mem_ctx, uint8_t,
+                                                  OUTVEC_ALLOC_SIZE);
+                       if (outhdr == NULL) {
+                               return NT_STATUS_NO_MEMORY;
+                       }
                }
 
                outbody = outhdr + SMB2_HDR_BODY;
@@ -1324,7 +1365,9 @@ NTSTATUS smbd_smb2_request_pending_queue(struct 
smbd_smb2_request *req,
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
-               data_blob_clear_free(&req->first_key);
+               if (req->first_key.length > 0) {
+                       data_blob_clear_free(&req->first_key);
+               }
 
                req->current_idx = 1;
 
@@ -1355,7 +1398,9 @@ NTSTATUS smbd_smb2_request_pending_queue(struct 
smbd_smb2_request *req,
                        SIVAL(outhdr, SMB2_HDR_FLAGS, flags);
                }
        }
-       data_blob_clear_free(&req->last_key);
+       if (req->last_key.length > 0) {
+               data_blob_clear_free(&req->last_key);
+       }
 
        defer_endtime = timeval_current_ofs_usec(defer_time);
        req->async_te = tevent_add_timer(req->sconn->ev_ctx,
@@ -2310,7 +2355,7 @@ static NTSTATUS smbd_smb2_request_reply(struct 
smbd_smb2_request *req)
                        return NT_STATUS_NO_MEMORY;
                }
 
-               tf = talloc_zero_array(req->out.vector, uint8_t,
+               tf = talloc_zero_array(req, uint8_t,
                                       SMB2_TF_HDR_SIZE);
                if (tf == NULL) {
                        return NT_STATUS_NO_MEMORY;
@@ -2345,7 +2390,9 @@ static NTSTATUS smbd_smb2_request_reply(struct 
smbd_smb2_request *req)
                        return status;
                }
        }
-       data_blob_clear_free(&req->last_key);
+       if (req->last_key.length > 0) {
+               data_blob_clear_free(&req->last_key);
+       }
 
        req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ;
 
@@ -2419,7 +2466,9 @@ static NTSTATUS smbd_smb2_request_reply(struct 
smbd_smb2_request *req)
                        return status;
                }
        }
-       data_blob_clear_free(&req->first_key);
+       if (req->first_key.length > 0) {
+               data_blob_clear_free(&req->first_key);
+       }
 
        /* I am a sick, sick man... :-). Sendfile hack ... JRA. */
        if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) &&
@@ -2540,7 +2589,7 @@ NTSTATUS smbd_smb2_request_done_ex(struct 
smbd_smb2_request *req,
                         */
                        uint8_t *pad;
 
-                       pad = talloc_zero_array(req->out.vector,
+                       pad = talloc_zero_array(req,
                                                uint8_t, pad_size);
                        if (pad == NULL) {
                                return smbd_smb2_request_error(req,
@@ -2563,7 +2612,7 @@ NTSTATUS smbd_smb2_request_done_ex(struct 
smbd_smb2_request *req,
                        old_dyn = SMBD_SMB2_OUT_DYN_PTR(req);
 
                        new_size = old_size + pad_size;
-                       new_dyn = talloc_zero_array(req->out.vector,
+                       new_dyn = talloc_zero_array(req,
                                               uint8_t, new_size);
                        if (new_dyn == NULL) {
                                return smbd_smb2_request_error(req,
@@ -2590,6 +2639,7 @@ NTSTATUS smbd_smb2_request_error_ex(struct 
smbd_smb2_request *req,
                                    const char *location)
 {
        DATA_BLOB body;
+       DATA_BLOB _dyn;
        uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req);
        size_t unread_bytes = smbd_smb2_unread_bytes(req);
 
@@ -2631,12 +2681,7 @@ NTSTATUS smbd_smb2_request_error_ex(struct 
smbd_smb2_request *req,
                 * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for
                 * 1 byte without having to do an alloc.
                 */
-               info = talloc_zero_array(req->out.vector,


-- 
Samba Shared Repository

Reply via email to