Commit e4d3e6b5 authored by Namjae Jeon's avatar Namjae Jeon Committed by Steve French

ksmbd: replace sessions list in connection with xarray

Replace sessions list in connection with xarray.
Signed-off-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
Reviewed-by: default avatarHyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 8849e754
...@@ -36,6 +36,7 @@ void ksmbd_conn_free(struct ksmbd_conn *conn) ...@@ -36,6 +36,7 @@ void ksmbd_conn_free(struct ksmbd_conn *conn)
list_del(&conn->conns_list); list_del(&conn->conns_list);
write_unlock(&conn_list_lock); write_unlock(&conn_list_lock);
xa_destroy(&conn->sessions);
kvfree(conn->request_buf); kvfree(conn->request_buf);
kfree(conn->preauth_info); kfree(conn->preauth_info);
kfree(conn); kfree(conn);
...@@ -66,12 +67,12 @@ struct ksmbd_conn *ksmbd_conn_alloc(void) ...@@ -66,12 +67,12 @@ struct ksmbd_conn *ksmbd_conn_alloc(void)
init_waitqueue_head(&conn->req_running_q); init_waitqueue_head(&conn->req_running_q);
INIT_LIST_HEAD(&conn->conns_list); INIT_LIST_HEAD(&conn->conns_list);
INIT_LIST_HEAD(&conn->sessions);
INIT_LIST_HEAD(&conn->requests); INIT_LIST_HEAD(&conn->requests);
INIT_LIST_HEAD(&conn->async_requests); INIT_LIST_HEAD(&conn->async_requests);
spin_lock_init(&conn->request_lock); spin_lock_init(&conn->request_lock);
spin_lock_init(&conn->credits_lock); spin_lock_init(&conn->credits_lock);
ida_init(&conn->async_ida); ida_init(&conn->async_ida);
xa_init(&conn->sessions);
spin_lock_init(&conn->llist_lock); spin_lock_init(&conn->llist_lock);
INIT_LIST_HEAD(&conn->lock_list); INIT_LIST_HEAD(&conn->lock_list);
......
...@@ -55,7 +55,7 @@ struct ksmbd_conn { ...@@ -55,7 +55,7 @@ struct ksmbd_conn {
struct nls_table *local_nls; struct nls_table *local_nls;
struct list_head conns_list; struct list_head conns_list;
/* smb session 1 per user */ /* smb session 1 per user */
struct list_head sessions; struct xarray sessions;
unsigned long last_active; unsigned long last_active;
/* How many request are running currently */ /* How many request are running currently */
atomic_t req_running; atomic_t req_running;
......
...@@ -152,8 +152,6 @@ void ksmbd_session_destroy(struct ksmbd_session *sess) ...@@ -152,8 +152,6 @@ void ksmbd_session_destroy(struct ksmbd_session *sess)
if (!atomic_dec_and_test(&sess->refcnt)) if (!atomic_dec_and_test(&sess->refcnt))
return; return;
list_del(&sess->sessions_entry);
down_write(&sessions_table_lock); down_write(&sessions_table_lock);
hash_del(&sess->hlist); hash_del(&sess->hlist);
up_write(&sessions_table_lock); up_write(&sessions_table_lock);
...@@ -181,42 +179,28 @@ static struct ksmbd_session *__session_lookup(unsigned long long id) ...@@ -181,42 +179,28 @@ static struct ksmbd_session *__session_lookup(unsigned long long id)
return NULL; return NULL;
} }
void ksmbd_session_register(struct ksmbd_conn *conn, int ksmbd_session_register(struct ksmbd_conn *conn,
struct ksmbd_session *sess) struct ksmbd_session *sess)
{ {
sess->conn = conn; sess->conn = conn;
list_add(&sess->sessions_entry, &conn->sessions); return xa_err(xa_store(&conn->sessions, sess->id, sess, GFP_KERNEL));
} }
void ksmbd_sessions_deregister(struct ksmbd_conn *conn) void ksmbd_sessions_deregister(struct ksmbd_conn *conn)
{ {
struct ksmbd_session *sess; struct ksmbd_session *sess;
unsigned long id;
while (!list_empty(&conn->sessions)) { xa_for_each(&conn->sessions, id, sess) {
sess = list_entry(conn->sessions.next, xa_erase(&conn->sessions, sess->id);
struct ksmbd_session,
sessions_entry);
ksmbd_session_destroy(sess); ksmbd_session_destroy(sess);
} }
} }
static bool ksmbd_session_id_match(struct ksmbd_session *sess,
unsigned long long id)
{
return sess->id == id;
}
struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn, struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
unsigned long long id) unsigned long long id)
{ {
struct ksmbd_session *sess = NULL; return xa_load(&conn->sessions, id);
list_for_each_entry(sess, &conn->sessions, sessions_entry) {
if (ksmbd_session_id_match(sess, id))
return sess;
}
return NULL;
} }
int get_session(struct ksmbd_session *sess) int get_session(struct ksmbd_session *sess)
...@@ -314,7 +298,6 @@ static struct ksmbd_session *__session_create(int protocol) ...@@ -314,7 +298,6 @@ static struct ksmbd_session *__session_create(int protocol)
goto error; goto error;
set_session_flag(sess, protocol); set_session_flag(sess, protocol);
INIT_LIST_HEAD(&sess->sessions_entry);
xa_init(&sess->tree_conns); xa_init(&sess->tree_conns);
INIT_LIST_HEAD(&sess->ksmbd_chann_list); INIT_LIST_HEAD(&sess->ksmbd_chann_list);
INIT_LIST_HEAD(&sess->rpc_handle_list); INIT_LIST_HEAD(&sess->rpc_handle_list);
......
...@@ -57,7 +57,6 @@ struct ksmbd_session { ...@@ -57,7 +57,6 @@ struct ksmbd_session {
__u8 smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE]; __u8 smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE];
__u8 smb3signingkey[SMB3_SIGN_KEY_SIZE]; __u8 smb3signingkey[SMB3_SIGN_KEY_SIZE];
struct list_head sessions_entry;
struct ksmbd_file_table file_table; struct ksmbd_file_table file_table;
atomic_t refcnt; atomic_t refcnt;
}; };
...@@ -84,8 +83,8 @@ void ksmbd_session_destroy(struct ksmbd_session *sess); ...@@ -84,8 +83,8 @@ void ksmbd_session_destroy(struct ksmbd_session *sess);
struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id); struct ksmbd_session *ksmbd_session_lookup_slowpath(unsigned long long id);
struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn, struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn,
unsigned long long id); unsigned long long id);
void ksmbd_session_register(struct ksmbd_conn *conn, int ksmbd_session_register(struct ksmbd_conn *conn,
struct ksmbd_session *sess); struct ksmbd_session *sess);
void ksmbd_sessions_deregister(struct ksmbd_conn *conn); void ksmbd_sessions_deregister(struct ksmbd_conn *conn);
struct ksmbd_session *ksmbd_session_lookup_all(struct ksmbd_conn *conn, struct ksmbd_session *ksmbd_session_lookup_all(struct ksmbd_conn *conn,
unsigned long long id); unsigned long long id);
......
...@@ -588,7 +588,8 @@ int smb2_check_user_session(struct ksmbd_work *work) ...@@ -588,7 +588,8 @@ int smb2_check_user_session(struct ksmbd_work *work)
return -EINVAL; return -EINVAL;
} }
static void destroy_previous_session(struct ksmbd_user *user, u64 id) static void destroy_previous_session(struct ksmbd_conn *conn,
struct ksmbd_user *user, u64 id)
{ {
struct ksmbd_session *prev_sess = ksmbd_session_lookup_slowpath(id); struct ksmbd_session *prev_sess = ksmbd_session_lookup_slowpath(id);
struct ksmbd_user *prev_user; struct ksmbd_user *prev_user;
...@@ -607,6 +608,7 @@ static void destroy_previous_session(struct ksmbd_user *user, u64 id) ...@@ -607,6 +608,7 @@ static void destroy_previous_session(struct ksmbd_user *user, u64 id)
} }
put_session(prev_sess); put_session(prev_sess);
xa_erase(&conn->sessions, prev_sess->id);
ksmbd_session_destroy(prev_sess); ksmbd_session_destroy(prev_sess);
} }
...@@ -1439,7 +1441,7 @@ static int ntlm_authenticate(struct ksmbd_work *work) ...@@ -1439,7 +1441,7 @@ static int ntlm_authenticate(struct ksmbd_work *work)
/* Check for previous session */ /* Check for previous session */
prev_id = le64_to_cpu(req->PreviousSessionId); prev_id = le64_to_cpu(req->PreviousSessionId);
if (prev_id && prev_id != sess->id) if (prev_id && prev_id != sess->id)
destroy_previous_session(user, prev_id); destroy_previous_session(conn, user, prev_id);
if (sess->state == SMB2_SESSION_VALID) { if (sess->state == SMB2_SESSION_VALID) {
/* /*
...@@ -1561,7 +1563,7 @@ static int krb5_authenticate(struct ksmbd_work *work) ...@@ -1561,7 +1563,7 @@ static int krb5_authenticate(struct ksmbd_work *work)
/* Check previous session */ /* Check previous session */
prev_sess_id = le64_to_cpu(req->PreviousSessionId); prev_sess_id = le64_to_cpu(req->PreviousSessionId);
if (prev_sess_id && prev_sess_id != sess->id) if (prev_sess_id && prev_sess_id != sess->id)
destroy_previous_session(sess->user, prev_sess_id); destroy_previous_session(conn, sess->user, prev_sess_id);
if (sess->state == SMB2_SESSION_VALID) if (sess->state == SMB2_SESSION_VALID)
ksmbd_free_user(sess->user); ksmbd_free_user(sess->user);
...@@ -1650,7 +1652,9 @@ int smb2_sess_setup(struct ksmbd_work *work) ...@@ -1650,7 +1652,9 @@ int smb2_sess_setup(struct ksmbd_work *work)
goto out_err; goto out_err;
} }
rsp->hdr.SessionId = cpu_to_le64(sess->id); rsp->hdr.SessionId = cpu_to_le64(sess->id);
ksmbd_session_register(conn, sess); rc = ksmbd_session_register(conn, sess);
if (rc)
goto out_err;
} else if (conn->dialect >= SMB30_PROT_ID && } else if (conn->dialect >= SMB30_PROT_ID &&
(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) && (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL) &&
req->Flags & SMB2_SESSION_REQ_FLAG_BINDING) { req->Flags & SMB2_SESSION_REQ_FLAG_BINDING) {
...@@ -1828,6 +1832,7 @@ int smb2_sess_setup(struct ksmbd_work *work) ...@@ -1828,6 +1832,7 @@ int smb2_sess_setup(struct ksmbd_work *work)
if (sess->user && sess->user->flags & KSMBD_USER_FLAG_DELAY_SESSION) if (sess->user && sess->user->flags & KSMBD_USER_FLAG_DELAY_SESSION)
try_delay = true; try_delay = true;
xa_erase(&conn->sessions, sess->id);
ksmbd_session_destroy(sess); ksmbd_session_destroy(sess);
work->sess = NULL; work->sess = NULL;
if (try_delay) if (try_delay)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment