[Patch] make sure credits are granted properly for compound requests

Jeremy Allison jra at samba.org
Mon Nov 14 15:39:21 MST 2011


On Mon, Nov 14, 2011 at 02:02:35PM -0800, Jeremy Allison wrote:
> On Mon, Nov 14, 2011 at 06:54:06PM +0100, Christian M Ambach wrote:
> > Hi Jeremy, hi Metze,
> > 
> > I've made a patch that makes sure that smbd grants all credits requested in the
> > individual requests of a compound request instead of just for the last request
> > of the compound.
> > Otherwise a client can be left without credits.
> > 
> > Behavior however is still different to Windows as Windows grants all credits
> > just in the last reply and not individually.
> > 
> > Shall I refine the patch to we match Windows behavior or put it into Samba
> > as-is?
> 
> I don't think this patch is quite right - if the last element
> in a compound set goes async we'll end up counting the credits
> twice with this fix.
> 
> I am testing a modified version that should make us behave
> identically to Windows. Give me a few hours to test..

Ok - this seems to work well for me. Can you test it out
and let me know ?

Thanks,

Jeremy.
-------------- next part --------------
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 33e95ad..b1f301b 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -517,13 +517,24 @@ static void smb2_calculate_credits(const struct smbd_smb2_request *inreq,
 				struct smbd_smb2_request *outreq)
 {
 	int count, idx;
+	uint16_t total_credits = 0;
 
 	count = outreq->out.vector_count;
 
 	for (idx=1; idx < count; idx += 3) {
+		uint8_t *outhdr = (uint8_t *)outreq->out.vector[idx].iov_base;
 		smb2_set_operation_credit(outreq->sconn,
 			&inreq->in.vector[idx],
 			&outreq->out.vector[idx]);
+		/* To match Windows, count up what we
+		   just granted. */
+		total_credits += SVAL(outhdr, SMB2_HDR_CREDIT);
+		/* Set to zero in all but the last reply. */
+		if (idx + 3 < count) {
+			SSVAL(outhdr, SMB2_HDR_CREDIT, 0);
+		} else {
+			SSVAL(outhdr, SMB2_HDR_CREDIT, total_credits);
+		}
 	}
 }
 
@@ -1836,11 +1847,9 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
 
 	smb2_setup_nbt_length(req->out.vector, req->out.vector_count);
 
-	/* Set credit for this operation (zero credits if this
+	/* Set credit for these operations (zero credits if this
 	   is a final reply for an async operation). */
-	smb2_set_operation_credit(req->sconn,
-			&req->in.vector[i],
-			&req->out.vector[i]);
+	smb2_calculate_credits(req, req);
 
 	if (req->do_signing) {
 		NTSTATUS status;


More information about the samba-technical mailing list