From c1d7bbfc5e081875053723d1a69eb2cf341eaaf1 Mon Sep 17 00:00:00 2001 From: Gael Blivet Date: Thu, 9 Jul 2026 02:01:06 +0200 Subject: [PATCH] ksmbd: fix durable handle v2 default timeout units (60 -> 60000) When a client's Durable Handle Request V2 sets Timeout=0 ("let the server choose"), fp->durable_timeout was set to 60. Every other use of this field is in milliseconds: DURABLE_HANDLE_MAX_TIMEOUT (300000) in smb2pdu.h, the nonzero branch immediately above (min_t(unsigned int, dh_info.timeout, DURABLE_HANDLE_MAX_TIMEOUT), where dh_info.timeout is the wire value and already milliseconds per spec), and the scavenger in vfs_cache.c, which adds it directly to jiffies_to_msecs(jiffies). 60 is off by 1000x: the handle becomes scavenger-eligible 60 milliseconds after close instead of 60 seconds. A client requesting Timeout=0 is relying entirely on the server's default to cover the gap between a dropped connection and its reconnect -- 60ms is not enough time for even a fast network blip to be detected and reconnected, so any real disruption loses the race and a subsequent DH2C reconnect fails with a durable-handle lookup miss instead of succeeding. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Gael Blivet Signed-off-by: Namjae Jeon --- fs/smb/server/smb2pdu.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 41d60c214a07..a05f2ccf0b3e 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -4186,10 +4186,17 @@ int smb2_open(struct ksmbd_work *work) min_t(unsigned int, dh_info.timeout, DURABLE_HANDLE_MAX_TIMEOUT); else - fp->durable_timeout = 60; + fp->durable_timeout = 60000; } } + /* + * conn->is_aapl detection above (this function's create-context + * parsing) is skipped on the reconnect path below, since a + * reconnect always arrives on a fresh connection -- if the client + * cares, it sends its own AAPL context on this same CREATE, which + * this function's normal (non-reconnect) parsing already handles. + */ reconnected_fp: rsp->StructureSize = cpu_to_le16(89); opinfo = opinfo_get(fp);