[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