From 6b4cf9a3785390b9da78ac29457f35bdd7d4f54a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Jun 2014 17:10:45 -0700 Subject: [PATCH 1/3] s3: smb2: Remove unused code from remove_pending_lock(). SMB2 blocking locks can only have one lock per request, so there can never be any previous locks to remove. Signed-off-by: Jeremy Allison --- source3/smbd/smb2_lock.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index 5da14e9..1236f4f 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -664,19 +664,6 @@ static void remove_pending_lock(struct smbd_smb2_lock_state *state, blr); TALLOC_FREE(br_lck); } - - /* Remove the locks we already got. */ - - for(i = blr->lock_num - 1; i >= 0; i--) { - struct smbd_lock_element *e = &state->locks[i]; - - do_unlock(blr->fsp->conn->sconn->msg_ctx, - blr->fsp, - e->smblctx, - e->count, - e->offset, - WINDOWS_LOCK); - } } /**************************************************************** -- 2.0.0.526.g5318336 From 43c0b8844ae9e395a496b2e413f5a474c1a7844d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 Jun 2014 12:01:56 -0700 Subject: [PATCH 2/3] s3: smb2: Simplify logic in reprocess_blocked_smb2_lock(). SMB2 blocking locks can only have one lock per request, so there can never be any other locks to wait for. Signed-off-by: Jeremy Allison --- source3/smbd/smb2_lock.c | 55 ++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index 1236f4f..11cef43 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -677,6 +677,8 @@ static void reprocess_blocked_smb2_lock(struct smbd_smb2_request *smb2req, NTSTATUS status = NT_STATUS_UNSUCCESSFUL; struct blocking_lock_record *blr = NULL; struct smbd_smb2_lock_state *state = NULL; + struct byte_range_lock *br_lck = NULL; + struct smbd_lock_element *e = NULL; files_struct *fsp = NULL; if (!smb2req->subreq) { @@ -690,34 +692,30 @@ static void reprocess_blocked_smb2_lock(struct smbd_smb2_request *smb2req, blr = state->blr; fsp = blr->fsp; - /* Try and finish off getting all the outstanding locks. */ - - for (; blr->lock_num < state->lock_count; blr->lock_num++) { - struct byte_range_lock *br_lck = NULL; - struct smbd_lock_element *e = &state->locks[blr->lock_num]; - - br_lck = do_lock(fsp->conn->sconn->msg_ctx, - fsp, - e->smblctx, - e->count, - e->offset, - e->brltype, - WINDOWS_LOCK, - true, - &status, - &blr->blocking_smblctx, - blr); + /* We can only have one blocked lock in SMB2. */ + SMB_ASSERT(state->lock_count == 1); + SMB_ASSERT(blr->lock_num == 0); - TALLOC_FREE(br_lck); + /* Try and get the outstanding lock. */ + e = &state->locks[blr->lock_num]; - if (NT_STATUS_IS_ERR(status)) { - break; - } - } + br_lck = do_lock(fsp->conn->sconn->msg_ctx, + fsp, + e->smblctx, + e->count, + e->offset, + e->brltype, + WINDOWS_LOCK, + true, + &status, + &blr->blocking_smblctx, + blr); - if(blr->lock_num == state->lock_count) { + TALLOC_FREE(br_lck); + + if (NT_STATUS_IS_OK(status)) { /* - * Success - we got all the locks. + * Success - we got the lock. */ DEBUG(3,("reprocess_blocked_smb2_lock SUCCESS file = %s, " @@ -742,7 +740,7 @@ static void reprocess_blocked_smb2_lock(struct smbd_smb2_request *smb2req, } /* - * We couldn't get the locks for this record on the list. + * We couldn't get the lock for this record. * If the time has expired, return a lock error. */ @@ -754,18 +752,15 @@ static void reprocess_blocked_smb2_lock(struct smbd_smb2_request *smb2req, } /* - * Still can't get all the locks - keep waiting. + * Still can't get the lock - keep waiting. */ - DEBUG(10,("reprocess_blocked_smb2_lock: only got %d locks of %d needed " + DEBUG(10,("reprocess_blocked_smb2_lock: failed to get lock " "for file %s, %s. Still waiting....\n", - (int)blr->lock_num, - (int)state->lock_count, fsp_str_dbg(fsp), fsp_fnum_dbg(fsp))); return; - } /**************************************************************** -- 2.0.0.526.g5318336 From be75216b59503c5cb7d2b20bf878416571b42d27 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 Jun 2014 12:08:46 -0700 Subject: [PATCH 3/3] s3: SMB2 : Fix leak of blocking lock records in the database. Based on a fix from Hemanth Thummala Bug #10673 - Increasing response times for byte range unlock requests. The previous refactoring makes it obvious we need to call remove_pending_lock() in all places where we are returning from the SMB2 blocking lock call. https://bugzilla.samba.org/show_bug.cgi?id=10673 Signed-off-by: Jeremy Allison --- source3/smbd/smb2_lock.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index 11cef43..23b9913 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -724,6 +724,7 @@ static void reprocess_blocked_smb2_lock(struct smbd_smb2_request *smb2req, fsp_fnum_dbg(fsp), (int)state->lock_count)); + remove_pending_lock(state, blr); tevent_req_done(smb2req->subreq); return; } -- 2.0.0.526.g5318336