From: Ralph Boehme Date: Tue, 25 Nov 2025 14:58:27 +0000 (+0100) Subject: scavenger: update scavenger_add_timer() for Persistent Handles X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=07db14278092fd5c5113b21def3a64680b1dee32;p=thirdparty%2Fsamba.git scavenger: update scavenger_add_timer() for Persistent Handles With Persistent Handles global->disconnect_time might be 0 if a process or node crashed and global->server_id won't be set to the special disconnected id. Due to a race there might the open record might already be gone, so handle that as well to still allow cleanup of locking.tdb and brlock.tdb records. Signed-off-by: Ralph Boehme Reviewed-by: Anoop C S --- diff --git a/source3/smbd/scavenger.c b/source3/smbd/scavenger.c index 9d9a7c5df23..674c3b9a4f2 100644 --- a/source3/smbd/scavenger.c +++ b/source3/smbd/scavenger.c @@ -635,25 +635,62 @@ static void scavenger_add_timer(struct smbd_scavenger_state *state, const struct smbXsrv_open_global0 *global = NULL; struct timeval until; struct file_id_buf idbuf; - struct timeval disconnect_time; + NTTIME disconnect_time = 0; + uint32_t durable_timeout_msec = 0; + struct timeval disconnect_timeval; uint64_t timeout_usec; NTSTATUS status; status = smbXsrv_open_global_lookup(frame, (uint32_t)msg->open_persistent_id, &global); - if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { + DBG_DEBUG("global open [%" PRIx64 "] already gone\n", + msg->open_persistent_id); + } else if (!NT_STATUS_IS_OK(status)) { DBG_WARNING("smbXsrv_open_global_lookup [%" PRIx64 "] failed: %s\n", msg->open_persistent_id, nt_errstr(status)); goto done; } - SMB_ASSERT(server_id_is_disconnected(&global->server_id)); - - nttime_to_timeval(&disconnect_time, global->disconnect_time); - timeout_usec = UINT64_C(1000) * global->durable_timeout_msec; - until = timeval_add(&disconnect_time, + if (global != NULL) { + if (!global->persistent) { + if (!server_id_is_disconnected(&global->server_id)) { + DBG_ERR("Open [0x%"PRIx64"] fileid [%s] is " + "not marked disconnected\n", + msg->open_persistent_id, + file_id_str_buf(msg->file_id, &idbuf)); + goto done; + } + if (global->disconnect_time == 0) { + DBG_ERR("Open [0x%"PRIx64"] fileid [%s] without " + "disconnect_time\n", + msg->open_persistent_id, + file_id_str_buf(msg->file_id, &idbuf)); + } + } else { + if (serverid_exists(&global->server_id)) { + struct server_id_buf sidbuf; + DBG_ERR("Open [0x%"PRIx64"] fileid [%s] pid [%s] " + "still around\n", + msg->open_persistent_id, + file_id_str_buf(msg->file_id, &idbuf), + server_id_str_buf(global->server_id, + &sidbuf)); + goto done; + } + } + disconnect_time = global->disconnect_time; + durable_timeout_msec = global->durable_timeout_msec; + } + if (disconnect_time != 0) { + nttime_to_timeval(&disconnect_timeval, disconnect_time); + } else { + GetTimeOfDay(&disconnect_timeval); + } + timeout_usec = UINT64_C(1000) * durable_timeout_msec; + until = timeval_add(&disconnect_timeval, timeout_usec / 1000000, timeout_usec % 1000000);