Second part of bugfix for bug #8335 - file copy aborts with smb2_validate_message_id...
authorJeremy Allison <jra@samba.org>
Fri, 29 Jul 2011 18:17:03 +0000 (11:17 -0700)
committerKarolin Seeger <kseeger@samba.org>
Sun, 31 Jul 2011 19:11:43 +0000 (21:11 +0200)
Modify the credit granting algorithm to closer to what I believe
Windows does.

Split up max_credits into 1/16ths, and then scale
the requested credits by how many 16ths have been
currently granted. Less than 1/16th == grant all
requested (100%), scale down as more have been
granted. Never ask for less than 1 if the client
asked for at least 1.

source3/smbd/smb2_server.c

index c5c7a8e4384128324ed8e87c139f23e560488f50..b77c6366c6254589a99380670360b84ea150a191 100644 (file)
@@ -452,9 +452,30 @@ static void smb2_set_operation_credit(struct smbd_server_connection *sconn,
 
        SMB_ASSERT(sconn->smb2.max_credits >= sconn->smb2.credits_granted);
 
-       /* Remember what we gave out. */
-       credits_granted = MIN(credits_requested, (sconn->smb2.max_credits -
-               sconn->smb2.credits_granted));
+       if (credits_requested) {
+               uint16_t modified_credits_requested;
+               uint32_t multiplier;
+
+               /*
+                * Split up max_credits into 1/16ths, and then scale
+                * the requested credits by how many 16ths have been
+                * currently granted. Less than 1/16th == grant all
+                * requested (100%), scale down as more have been
+                * granted. Never ask for less than 1 as the client
+                * asked for at least 1. JRA.
+                */
+
+               multiplier = 16 - (((sconn->smb2.credits_granted * 16) / sconn->smb2.max_credits) % 16);
+
+               modified_credits_requested = (multiplier * credits_requested) / 16;
+               if (modified_credits_requested == 0) {
+                       modified_credits_requested = 1;
+               }
+
+               /* Remember what we gave out. */
+               credits_granted = MIN(modified_credits_requested,
+                                       (sconn->smb2.max_credits - sconn->smb2.credits_granted));
+       }
 
        if (credits_granted == 0 && sconn->smb2.credits_granted == 0) {
                /* First negprot packet, or ensure the client credits can