summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2019-08-15 18:17:47 +0200
committerStefan Metzmacher <metze@samba.org>2019-09-09 16:04:30 +0000
commit9f46f3b0e722d993a650fc3659e842aad08837a6 (patch)
tree53ab6c019a5ecafe564b0c744b4a61d57cd2716a
parentd857b21d4fec18aa71f9bec4343924053dd9f083 (diff)
downloadsamba-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.c25
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;
}