summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2014-07-02 20:40:49 -0700
committerKarolin Seeger <kseeger@samba.org>2014-07-15 12:46:16 +0200
commit01753e8409497f8f82dd637a0ad8402da9464d5c (patch)
tree29715d6a122df12748fbae34d6e22e5932f507be /source3
parent6484211b6815765cf6e1dcb5b884e82c6edc8bae (diff)
downloadsamba-01753e8409497f8f82dd637a0ad8402da9464d5c.tar.gz
s3: smbd: Locking - treat lock timeout the same as any other error.
Allows the special case in process_blocking_lock_queue() that talks back to the client to be removed. Bug #10684 - SMB1 blocking locks can fail notification on unlock, causing client timeout. https://bugzilla.samba.org/show_bug.cgi?id=10684 Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Volker Lendecke <Volker.Lendecke@SerNet.DE> (cherry picked from commit cc9de6eb091159a84228b988c49261c46c301233)
Diffstat (limited to 'source3')
-rw-r--r--source3/smbd/blocking.c91
1 files changed, 38 insertions, 53 deletions
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 303585069d4..b6edb65c236 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -464,6 +464,7 @@ static bool process_lockingX(struct blocking_lock_record *blr)
bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
uint8_t *data;
NTSTATUS status = NT_STATUS_OK;
+ bool lock_timeout = lock_timed_out(blr);
data = discard_const_p(uint8_t, blr->req->buf)
+ ((large_file_format ? 20 : 10)*num_ulocks);
@@ -530,6 +531,14 @@ static bool process_lockingX(struct blocking_lock_record *blr)
}
/*
+ * Return an error to the client if we timed out.
+ */
+ if (lock_timeout) {
+ blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
+ return true;
+ }
+
+ /*
* Still can't get all the locks - keep waiting.
*/
@@ -550,6 +559,8 @@ static bool process_trans2(struct blocking_lock_record *blr)
{
char params[2];
NTSTATUS status;
+ bool lock_timeout = lock_timed_out(blr);
+
struct byte_range_lock *br_lck = do_lock(
blr->fsp->conn->sconn->msg_ctx,
blr->fsp,
@@ -566,6 +577,15 @@ static bool process_trans2(struct blocking_lock_record *blr)
if (!NT_STATUS_IS_OK(status)) {
if (ERROR_WAS_LOCK_DENIED(status)) {
+ if (lock_timeout) {
+ /*
+ * Return an error if we timed out
+ * and return true to get dequeued.
+ */
+ blocking_lock_reply_error(blr,
+ NT_STATUS_FILE_LOCK_CONFLICT);
+ return true;
+ }
/* Still can't get the lock, just keep waiting. */
return False;
}
@@ -765,6 +785,7 @@ void process_blocking_lock_queue(struct smbd_server_connection *sconn)
*/
for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) {
+ struct byte_range_lock *br_lck = NULL;
next = blr->next;
@@ -784,65 +805,29 @@ void process_blocking_lock_queue(struct smbd_server_connection *sconn)
SVAL(blr->req->inbuf,smb_flg),
false);
- if(blocking_lock_record_process(blr)) {
- struct byte_range_lock *br_lck = brl_get_locks(
- talloc_tos(), blr->fsp);
-
- DEBUG(10, ("BLR_process returned true: cancelling and "
- "removing lock. BLR = %p\n", blr));
-
- if (br_lck) {
- brl_lock_cancel(br_lck,
- blr->smblctx,
- messaging_server_id(sconn->msg_ctx),
- blr->offset,
- blr->count,
- blr->lock_flav,
- blr);
- TALLOC_FREE(br_lck);
- }
-
- DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr);
- TALLOC_FREE(blr);
+ if(!blocking_lock_record_process(blr)) {
+ DEBUG(10, ("still waiting for lock. BLR = %p\n", blr));
continue;
}
- /*
- * We couldn't get the locks for this record on the list.
- * If the time has expired, return a lock error.
- */
-
- if (lock_timed_out(blr)) {
- struct byte_range_lock *br_lck = brl_get_locks(
- talloc_tos(), blr->fsp);
-
- DEBUG(10, ("Lock timed out! BLR = %p\n", blr));
+ br_lck = brl_get_locks(talloc_tos(), blr->fsp);
- /*
- * Lock expired - throw away all previously
- * obtained locks and return lock error.
- */
-
- if (br_lck) {
- DEBUG(5,("process_blocking_lock_queue: "
- "pending lock for %s, file %s "
- "timed out.\n", fsp_fnum_dbg(blr->fsp),
- fsp_str_dbg(blr->fsp)));
-
- brl_lock_cancel(br_lck,
- blr->smblctx,
- messaging_server_id(sconn->msg_ctx),
- blr->offset,
- blr->count,
- blr->lock_flav,
- blr);
- TALLOC_FREE(br_lck);
- }
+ DEBUG(10, ("BLR_process returned true: cancelling and "
+ "removing lock. BLR = %p\n", blr));
- blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
- DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr);
- TALLOC_FREE(blr);
+ if (br_lck) {
+ brl_lock_cancel(br_lck,
+ blr->smblctx,
+ messaging_server_id(sconn->msg_ctx),
+ blr->offset,
+ blr->count,
+ blr->lock_flav,
+ blr);
+ TALLOC_FREE(br_lck);
}
+
+ DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr);
+ TALLOC_FREE(blr);
}
recalc_brl_timeout(sconn);