[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