From 9d33ec667f97b77e6d1c39f3833800299f0510c6 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 Reviewed-by: Ira Cooper Reviewed-by: Volker Lendecke (cherry picked from commit 508c09c6a019458bb0290fbf284e73c24feddb0e) --- 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 2ee7afa..ba61eba 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 0c4addfb438aede3b8d88407b5d2aa5b81b694fd 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 Reviewed-by: Ira Cooper Reviewed-by: Volker Lendecke (cherry picked from commit 1a02a1e6aa15c028a848585d66cecbbdda8015b3) --- 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 ba61eba..6c81f5c 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 5f3803d5c6fed9fca154cab1da770c2f9073f987 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 Reviewed-by: Ira Cooper Reviewed-by: Volker Lendecke Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Mon Jun 30 14:59:16 CEST 2014 on sn-devel-104 (cherry picked from commit cee1531e551e5ccd5ccd4a55de226ad686919486) --- 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 6c81f5c..52698f3 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