From: Stefan Metzmacher Date: Thu, 15 Aug 2019 12:21:38 +0000 (+0200) Subject: s3:blocking: fix posix lock retry X-Git-Tag: talloc-2.3.1~972 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e8d719d31f885d7b6d5b317165f90ec40df169c9;p=thirdparty%2Fsamba.git s3:blocking: fix posix lock retry We should evaluate the timeout condition after the very last retry and not before. Otherwise we'd fail to retry when waiting for posix locks. The problem happens if the client provided timeout is smaller than the 1 sec (for testing temporary 15 secs) retry. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 Signed-off-by: Stefan Metzmacher Reviewed-by: Volker Lendecke --- 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); }