[PATCH v2 4/4] smb/server: fix session counter on session removal

Ze Tan <[email protected]>
Newsgroups org.kernel.vger.linux-cifs
Message-ID <[email protected]>
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 <[email protected]>
Reviewed-by: ChenXiaoSong <[email protected]>
---
 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 f023e0d2b8f0..1a0b2901ad21 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);
 		}
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.