]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:blocking: use dynamic posix lock wait intervals
authorStefan Metzmacher <metze@samba.org>
Thu, 15 Aug 2019 15:26:43 +0000 (17:26 +0200)
committerStefan Metzmacher <metze@samba.org>
Mon, 9 Sep 2019 14:23:39 +0000 (14:23 +0000)
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>
source3/smbd/blocking.c

index af889a10d62178abaf8fea5b1c2d622dd339b106..50e1d436eb75c30d554fe0ca997e5f65b79c5ca6 100644 (file)
@@ -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);
        }