From 0ab5a45392d02bc9c5af74c9cdd769422fb251d7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 6 Aug 2011 10:19:21 +0200 Subject: [PATCH] s3:smb2_server: make sure we grant credits on async read/write operations (bug #8357) Currently we skip, the "gone async" interim response on read and write, this caused the aio code path to grant 0 credits to the client in the read/write responses. metze Autobuild-User: Stefan Metzmacher Autobuild-Date: Sun Aug 7 22:23:57 CEST 2011 on sn-devel-104 (cherry picked from commit 47bffb9b9243dc72d7305cd9ec3e63e176841bf5) --- source3/smbd/smb2_server.c | 21 +++++++++++++++------ 1 files changed, 15 insertions(+), 6 deletions(-) diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index b77c636..0cc80ed 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -441,17 +441,26 @@ static void smb2_set_operation_credit(struct smbd_server_connection *sconn, const struct iovec *in_vector, struct iovec *out_vector) { + const uint8_t *inhdr = (const uint8_t *)in_vector->iov_base; uint8_t *outhdr = (uint8_t *)out_vector->iov_base; - uint16_t credits_requested = 0; + uint16_t credits_requested; + uint32_t out_flags; uint16_t credits_granted = 0; - if (in_vector != NULL) { - const uint8_t *inhdr = (const uint8_t *)in_vector->iov_base; - credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT); - } + credits_requested = SVAL(inhdr, SMB2_HDR_CREDIT); + out_flags = IVAL(outhdr, SMB2_HDR_FLAGS); SMB_ASSERT(sconn->smb2.max_credits >= sconn->smb2.credits_granted); + if (out_flags & SMB2_HDR_FLAG_ASYNC) { + /* + * In case we already send an async interim + * response, we should not grant + * credits on the final response. + */ + credits_requested = 0; + } + if (credits_requested) { uint16_t modified_credits_requested; uint32_t multiplier; @@ -1617,7 +1626,7 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req) /* Set credit for this operation (zero credits if this is a final reply for an async operation). */ smb2_set_operation_credit(req->sconn, - req->async ? NULL : &req->in.vector[i], + &req->in.vector[i], &req->out.vector[i]); if (req->do_signing) { -- 1.7.4.1