summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2019-08-15 17:26:43 +0200
committerStefan Metzmacher <metze@samba.org>2019-09-09 16:04:29 +0000
commit1fd0a52e6727b191aa008f7a260ad748d34d5870 (patch)
treed6394ee2903862304bd76e8dbd1075fe12db289d
parente91bae2bdb11c8466a42ae51660bb564de1aedc2 (diff)
downloadsamba-1fd0a52e6727b191aa008f7a260ad748d34d5870.tar.gz
s3:blocking: use dynamic posix lock wait intervals
We want to start with a short timeout (200ms) and slow down to larger timeouts up to 2s for the default value of "lock spin time". 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 15765644d2590d6549f8fcc01c39c56387eed654)
-rw-r--r--source3/smbd/blocking.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index af889a10d62..50e1d436eb7 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -102,6 +102,7 @@ struct smbd_smb1_do_locks_state {
struct smb_request *smbreq;
struct files_struct *fsp;
uint32_t timeout;
+ uint32_t polling_msecs;
struct timeval endtime;
bool large_offset; /* required for correct cancel */
enum brl_flavour lock_flav;
@@ -115,6 +116,32 @@ static void smbd_smb1_do_locks_retry(struct tevent_req *subreq);
static void smbd_smb1_blocked_locks_cleanup(
struct tevent_req *req, enum tevent_req_state req_state);
+static void smbd_smb1_do_locks_update_polling_msecs(
+ struct smbd_smb1_do_locks_state *state)
+{
+ /*
+ * The default lp_lock_spin_time() is 200ms.
+ *
+ * v_min is in the range of 0.002 to 20 secs
+ * (0.2 secs by default)
+ *
+ * v_max is in the range of 0.02 to 200 secs
+ * (2.0 secs by default)
+ *
+ * The typical steps are:
+ * 0.2, 0.4, 0.6, 0.8, ... 2.0
+ */
+ uint32_t v_min = MAX(2, MIN(20000, lp_lock_spin_time()));
+ uint32_t v_max = 10 * v_min;
+
+ if (state->polling_msecs >= v_max) {
+ state->polling_msecs = v_max;
+ return;
+ }
+
+ state->polling_msecs += v_min;
+}
+
struct tevent_req *smbd_smb1_do_locks_send(
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -237,9 +264,12 @@ struct tevent_req *smbd_smb1_do_locks_send(
if (blocking_smblctx == UINT64_MAX) {
struct timeval tmp;
- DBG_DEBUG("Blocked on a posix lock. Retry in one second\n");
+ smbd_smb1_do_locks_update_polling_msecs(state);
+
+ DBG_DEBUG("Blocked on a posix lock. Retry in %"PRIu32" msecs\n",
+ state->polling_msecs);
- tmp = timeval_current_ofs(1, 0);
+ tmp = timeval_current_ofs_msec(state->polling_msecs);
endtime = timeval_min(&endtime, &tmp);
}
@@ -373,9 +403,12 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req)
if (blocking_smblctx == UINT64_MAX) {
struct timeval tmp;
- DBG_DEBUG("Blocked on a posix lock. Retry in one second\n");
+ smbd_smb1_do_locks_update_polling_msecs(state);
+
+ DBG_DEBUG("Blocked on a posix lock. Retry in %"PRIu32" msecs\n",
+ state->polling_msecs);
- tmp = timeval_current_ofs(1, 0);
+ tmp = timeval_current_ofs_msec(state->polling_msecs);
endtime = timeval_min(&endtime, &tmp);
}