s3:smb2_server: make sure we grant credits on async read/write operations (bug #8357)
authorStefan Metzmacher <metze@samba.org>
Sat, 6 Aug 2011 08:19:21 +0000 (10:19 +0200)
committerStefan Metzmacher <metze@samba.org>
Sun, 7 Aug 2011 20:23:57 +0000 (22:23 +0200)
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 <metze@samba.org>
Autobuild-Date: Sun Aug  7 22:23:57 CEST 2011 on sn-devel-104

source3/smbd/smb2_server.c

index 288cc79b545f0f3ea506f2c36cfdb5a7b82d0e7d..e40c5944283f70161f9a250a69b85f8366ac324f 100644 (file)
@@ -444,17 +444,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;
@@ -1748,7 +1757,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) {