diff options
author | Stefan Metzmacher <metze@samba.org> | 2019-08-15 18:17:47 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2019-09-09 16:04:30 +0000 |
commit | 9f46f3b0e722d993a650fc3659e842aad08837a6 (patch) | |
tree | 53ab6c019a5ecafe564b0c744b4a61d57cd2716a | |
parent | d857b21d4fec18aa71f9bec4343924053dd9f083 (diff) | |
download | samba-9f46f3b0e722d993a650fc3659e842aad08837a6.tar.gz |
s3:blocking: use timeval_expired(&state->endtime) to stop processing
This is less racy than timeval_elapsed() > 0
as the current time is already expired and timeout = 0
will always work correct.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
(cherry picked from commit 5a841a43f9c4f862e2d7235429363b3066cf5850)
-rw-r--r-- | source3/smbd/blocking.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index a87d62d910a..9f64a86d3ee 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -159,9 +159,10 @@ struct tevent_req *smbd_smb1_do_locks_send( struct share_mode_lock *lck = NULL; struct server_id blocking_pid = { 0 }; uint64_t blocking_smblctx = 0; - struct timeval endtime; + struct timeval endtime = { 0 }; NTSTATUS status = NT_STATUS_OK; bool ok; + bool expired; req = tevent_req_create( mem_ctx, &state, struct smbd_smb1_do_locks_state); @@ -251,19 +252,28 @@ struct tevent_req *smbd_smb1_do_locks_send( state->timeout = lp_lock_spin_time(); } } + state->endtime = timeval_current_ofs_msec(state->timeout); DBG_DEBUG("timeout=%"PRIu32", blocking_smblctx=%"PRIu64"\n", state->timeout, blocking_smblctx); /* + * The client specified timeout expired + * avoid further retries. + * + * Otherwise keep waiting either waiting + * for changes in locking.tdb or the polling + * mode timers waiting for posix locks. + * * If the endtime is not elapsed yet, * it means we'll retry after a timeout. * In that case we'll have to return * NT_STATUS_FILE_LOCK_CONFLICT * instead of NT_STATUS_LOCK_NOT_GRANTED. */ - if (state->timeout == 0) { + expired = timeval_expired(&state->endtime); + if (expired) { status = state->deny_status; tevent_req_nterror(req, status); goto done; @@ -278,7 +288,6 @@ struct tevent_req *smbd_smb1_do_locks_send( TALLOC_FREE(lck); tevent_req_set_callback(subreq, smbd_smb1_do_locks_retry, req); - state->endtime = timeval_current_ofs_msec(state->timeout); endtime = state->endtime; if (blocking_smblctx == UINT64_MAX) { @@ -363,13 +372,13 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) struct smbd_smb1_do_locks_state *retry_state = tevent_req_data( retry_req, struct smbd_smb1_do_locks_state); struct share_mode_lock *lck; - struct timeval endtime; + struct timeval endtime = { 0 }; struct server_id blocking_pid = { 0 }; uint64_t blocking_smblctx = 0; struct tevent_req *subreq = NULL; NTSTATUS status; bool ok; - double elapsed; + bool expired; lck = get_existing_share_mode_lock(state, fsp->file_id); if (tevent_req_nomem(lck, req)) { @@ -393,7 +402,7 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) } /* - * The client specified timeout elapsed + * The client specified timeout expired * avoid further retries. * * Otherwise keep waiting either waiting @@ -406,8 +415,8 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) * NT_STATUS_FILE_LOCK_CONFLICT * instead of NT_STATUS_LOCK_NOT_GRANTED. */ - elapsed = timeval_elapsed(&state->endtime); - if (elapsed > 0) { + expired = timeval_expired(&state->endtime); + if (expired) { status = state->deny_status; goto done; } |