]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
smb: smbdirect: introduce smbdirect_connection_idle_timer_work()
authorStefan Metzmacher <metze@samba.org>
Wed, 27 Aug 2025 15:15:55 +0000 (17:15 +0200)
committerSteve French <stfrench@microsoft.com>
Thu, 16 Apr 2026 02:58:18 +0000 (21:58 -0500)
This is basically a copy of idle_connection_timer() in the client
and smb_direct_idle_connection_timer() in the server.
The only difference is that the server does not have logging.

Currently the callers set their own timer function after
smbdirect_socket_prepare_create(), but that will change
in the next steps...

Cc: Steve French <smfrench@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Long Li <longli@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/common/smbdirect/smbdirect_connection.c
fs/smb/common/smbdirect/smbdirect_internal.h
fs/smb/common/smbdirect/smbdirect_socket.c

index ce10aff54349bf65ae16a60a5d24972a958c22b4..6e4b7aa2440dd4ff42bc8a1a97be3fb1ed4983a6 100644 (file)
@@ -82,3 +82,34 @@ smbdirect_connection_reassembly_first_recv_io(struct smbdirect_socket *sc)
 
        return msg;
 }
+
+static void smbdirect_connection_idle_timer_work(struct work_struct *work)
+{
+       struct smbdirect_socket *sc =
+               container_of(work, struct smbdirect_socket, idle.timer_work.work);
+       const struct smbdirect_socket_parameters *sp = &sc->parameters;
+
+       if (sc->idle.keepalive != SMBDIRECT_KEEPALIVE_NONE) {
+               smbdirect_log_keep_alive(sc, SMBDIRECT_LOG_ERR,
+                       "%s => timeout sc->idle.keepalive=%s\n",
+                       smbdirect_socket_status_string(sc->status),
+                       sc->idle.keepalive == SMBDIRECT_KEEPALIVE_SENT ?
+                       "SENT" : "PENDING");
+               smbdirect_socket_schedule_cleanup(sc, -ETIMEDOUT);
+               return;
+       }
+
+       if (sc->status != SMBDIRECT_SOCKET_CONNECTED)
+               return;
+
+       /*
+        * Now use the keepalive timeout (instead of keepalive interval)
+        * in order to wait for a response
+        */
+       sc->idle.keepalive = SMBDIRECT_KEEPALIVE_PENDING;
+       mod_delayed_work(sc->workqueue, &sc->idle.timer_work,
+                        msecs_to_jiffies(sp->keepalive_timeout_msec));
+       smbdirect_log_keep_alive(sc, SMBDIRECT_LOG_INFO,
+               "schedule send of empty idle message\n");
+       queue_work(sc->workqueue, &sc->idle.immediate_work);
+}
index c946e53f94cd4281b95927b5b9ae4c617430e075..2d7c69f71ee064a8f8f8ff17a7d68b32a6cdf219 100644 (file)
@@ -32,4 +32,6 @@ static void __smbdirect_socket_schedule_cleanup(struct smbdirect_socket *sc,
                __func__, __LINE__, __error, &__force_status); \
 } while (0)
 
+static void smbdirect_connection_idle_timer_work(struct work_struct *work);
+
 #endif /* __FS_SMB_COMMON_SMBDIRECT_INTERNAL_H__ */
index ba7e3ac32d920c1160a73e1b8c6a3e63e19dbbd9..34971c2700eecf4426c4a8a507f485ea1091da58 100644 (file)
@@ -27,6 +27,8 @@ static void smbdirect_socket_prepare_create(struct smbdirect_socket *sc,
        sc->workqueue = workqueue;
 
        INIT_WORK(&sc->disconnect_work, smbdirect_socket_cleanup_work);
+
+       INIT_DELAYED_WORK(&sc->idle.timer_work, smbdirect_connection_idle_timer_work);
 }
 
 __maybe_unused /* this is temporary while this file is included in others */
@@ -67,7 +69,6 @@ static void smbdirect_socket_wake_up_all(struct smbdirect_socket *sc)
        wake_up_all(&sc->mr_io.cleanup.wait_queue);
 }
 
-__maybe_unused /* this is temporary while this file is included in others */
 static void __smbdirect_socket_schedule_cleanup(struct smbdirect_socket *sc,
                                                const char *macro_name,
                                                unsigned int lvl,