summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--selftest/knownfail.d/lock91
-rw-r--r--source3/smbd/blocking.c36
2 files changed, 25 insertions, 12 deletions
diff --git a/selftest/knownfail.d/lock9 b/selftest/knownfail.d/lock9
deleted file mode 100644
index 044622586eb..00000000000
--- a/selftest/knownfail.d/lock9
+++ /dev/null
@@ -1 +0,0 @@
-^samba3.smbtorture_s3.*.LOCK9B
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 81facc43154..587923aa5ec 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -319,6 +319,7 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req)
struct tevent_req *subreq = NULL;
NTSTATUS status;
bool ok;
+ double elapsed;
lck = get_existing_share_mode_lock(state, fsp->file_id);
if (tevent_req_nomem(lck, req)) {
@@ -341,6 +342,24 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req)
goto done;
}
+ /*
+ * The client specified timeout elapsed
+ * avoid further retries.
+ *
+ * Otherwise keep waiting either waiting
+ * for changes in locking.tdb or the polling
+ * mode timers waiting for posix locks.
+ */
+ elapsed = timeval_elapsed(&state->endtime);
+ if (elapsed > 0) {
+ /*
+ * On timeout we always return
+ * NT_STATUS_FILE_LOCK_CONFLICT
+ */
+ status = NT_STATUS_FILE_LOCK_CONFLICT;
+ goto done;
+ }
+
subreq = dbwrap_watched_watch_send(
state, state->ev, lck->data->record, blocking_pid);
if (tevent_req_nomem(subreq, req)) {
@@ -395,17 +414,12 @@ static void smbd_smb1_do_locks_retry(struct tevent_req *subreq)
DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
nt_errstr(status));
- if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
- double elapsed = timeval_elapsed(&state->endtime);
- if (elapsed > 0) {
- smbd_smb1_brl_finish_by_req(
- req, NT_STATUS_FILE_LOCK_CONFLICT);
- return;
- }
- /*
- * This is a posix lock retry. Just retry.
- */
- }
+ /*
+ * We ignore any errors here, it's most likely
+ * we just get NT_STATUS_OK or NT_STATUS_IO_TIMEOUT.
+ *
+ * In any case we can just give it a retry.
+ */
smbd_smb1_do_locks_try(req);
}