diff options
-rw-r--r-- | selftest/knownfail.d/lock9 | 1 | ||||
-rw-r--r-- | source3/smbd/blocking.c | 36 |
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); } |