From 7de5cf9bcf96bf2ee2ea2ad1d35a7b950f71161a Mon Sep 17 00:00:00 2001 From: Ze Tan Date: Fri, 14 Aug 2026 13:51:44 +0000 Subject: [PATCH] smb/server: fix session counter on session removal See the procedure below: smb2_sess_setup ksmbd_smb2_session_create __session_create hash_add(sessions_table, &sess->hlist, sess->id) ksmbd_counter_inc(KSMBD_COUNTER_SESSIONS) ksmbd_conn_handler_loop ksmbd_server_terminate_conn ksmbd_sessions_deregister hash_del(&sess->hlist) // do not decrement KSMBD_COUNTER_SESSIONS KSMBD_COUNTER_SESSIONS tracks sessions published in sessions_table, but session removal does not decrement it. The value therefore keeps growing after sessions are expired, rejected during registration, or removed on the last channel disconnect. Fixes: b38f99c1217a ("ksmbd: add procfs interface for runtime monitoring and statistics") Signed-off-by: Ze Tan Reviewed-by: ChenXiaoSong Signed-off-by: Namjae Jeon --- fs/smb/server/mgmt/user_session.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c index 087cf968a320..7022d5d656b4 100644 --- a/fs/smb/server/mgmt/user_session.c +++ b/fs/smb/server/mgmt/user_session.c @@ -413,6 +413,12 @@ void ksmbd_session_destroy(struct ksmbd_session *sess) kfree_sensitive(sess); } +static void ksmbd_session_remove_from_table(struct ksmbd_session *sess) +{ + hash_del(&sess->hlist); + ksmbd_counter_dec(KSMBD_COUNTER_SESSIONS); +} + struct ksmbd_session *__session_lookup(unsigned long long id) { struct ksmbd_session *sess; @@ -439,7 +445,7 @@ static void ksmbd_expire_session(struct ksmbd_conn *conn) time_after(jiffies, sess->last_active + SMB2_SESSION_TIMEOUT))) { xa_erase(&conn->sessions, sess->id); - hash_del(&sess->hlist); + ksmbd_session_remove_from_table(sess); ksmbd_session_destroy(sess); continue; } @@ -460,7 +466,7 @@ int ksmbd_session_register(struct ksmbd_conn *conn, KSMBD_DEFAULT_GFP)); if (ret) { down_write(&sessions_table_lock); - hash_del(&sess->hlist); + ksmbd_session_remove_from_table(sess); up_write(&sessions_table_lock); ksmbd_user_session_put(sess); } @@ -493,7 +499,7 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn) hash_for_each_safe(sessions_table, bkt, tmp, sess, hlist) { if (!ksmbd_chann_del(conn, sess) && xa_empty(&sess->ksmbd_chann_list)) { - hash_del(&sess->hlist); + ksmbd_session_remove_from_table(sess); down_write(&conn->session_lock); xa_erase(&conn->sessions, sess->id); up_write(&conn->session_lock); @@ -507,7 +513,7 @@ void ksmbd_sessions_deregister(struct ksmbd_conn *conn) ksmbd_chann_del(conn, sess); if (xa_empty(&sess->ksmbd_chann_list)) { xa_erase(&conn->sessions, sess->id); - hash_del(&sess->hlist); + ksmbd_session_remove_from_table(sess); if (atomic_dec_and_test(&sess->refcnt)) ksmbd_session_destroy(sess); }