summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/blocking.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index deb7f8f221..6c7c167ab5 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -72,6 +72,7 @@ static bool recalc_brl_timeout(void)
{
struct blocking_lock_record *blr;
struct timeval next_timeout;
+ int max_brl_timeout = lp_parm_int(-1, "brl", "recalctime", 5);
TALLOC_FREE(brl_timeout);
@@ -100,6 +101,25 @@ static bool recalc_brl_timeout(void)
return True;
}
+ /*
+ to account for unclean shutdowns by clients we need a
+ maximum timeout that we use for checking pending locks. If
+ we have any pending locks at all, then check if the pending
+ lock can continue at least every brl:recalctime seconds
+ (default 5 seconds).
+
+ This saves us needing to do a message_send_all() in the
+ SIGCHLD handler in the parent daemon. That
+ message_send_all() caused O(n^2) work to be done when IP
+ failovers happened in clustered Samba, which could make the
+ entire system unusable for many minutes.
+ */
+
+ if (max_brl_timeout > 0) {
+ struct timeval min_to = timeval_current_ofs(max_brl_timeout, 0);
+ next_timeout = timeval_min(&next_timeout, &min_to);
+ }
+
if (DEBUGLVL(10)) {
struct timeval cur, from_now;