diff options
Diffstat (limited to 'fs/smb/server/smb2pdu.c')
| -rw-r--r-- | fs/smb/server/smb2pdu.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index 2fcd0d4d1fb0..cbb31efdbaa2 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -39,6 +39,7 @@ #include "mgmt/user_session.h" #include "mgmt/ksmbd_ida.h" #include "ndr.h" +#include "stats.h" #include "transport_tcp.h" static void __wbuf(struct ksmbd_work *work, void **req, void **rsp) @@ -79,7 +80,13 @@ static inline bool check_session_id(struct ksmbd_conn *conn, u64 id) struct channel *lookup_chann_list(struct ksmbd_session *sess, struct ksmbd_conn *conn) { - return xa_load(&sess->ksmbd_chann_list, (long)conn); + struct channel *chann; + + down_read(&sess->chann_lock); + chann = xa_load(&sess->ksmbd_chann_list, (long)conn); + up_read(&sess->chann_lock); + + return chann; } /** @@ -1558,8 +1565,10 @@ binding_session: return -ENOMEM; chann->conn = conn; + down_write(&sess->chann_lock); old = xa_store(&sess->ksmbd_chann_list, (long)conn, chann, KSMBD_DEFAULT_GFP); + up_write(&sess->chann_lock); if (xa_is_err(old)) { kfree(chann); return xa_err(old); @@ -1651,8 +1660,10 @@ binding_session: return -ENOMEM; chann->conn = conn; + down_write(&sess->chann_lock); old = xa_store(&sess->ksmbd_chann_list, (long)conn, chann, KSMBD_DEFAULT_GFP); + up_write(&sess->chann_lock); if (xa_is_err(old)) { kfree(chann); return xa_err(old); @@ -2026,9 +2037,9 @@ int smb2_tree_connect(struct ksmbd_work *work) if (conn->posix_ext_supported) status.tree_conn->posix_extensions = true; - write_lock(&sess->tree_conns_lock); + down_write(&sess->tree_conns_lock); status.tree_conn->t_state = TREE_CONNECTED; - write_unlock(&sess->tree_conns_lock); + up_write(&sess->tree_conns_lock); rsp->StructureSize = cpu_to_le16(16); out_err1: if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE && share && @@ -2182,16 +2193,16 @@ int smb2_tree_disconnect(struct ksmbd_work *work) ksmbd_close_tree_conn_fds(work); - write_lock(&sess->tree_conns_lock); + down_write(&sess->tree_conns_lock); if (tcon->t_state == TREE_DISCONNECTED) { - write_unlock(&sess->tree_conns_lock); + up_write(&sess->tree_conns_lock); rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED; err = -ENOENT; goto err_out; } tcon->t_state = TREE_DISCONNECTED; - write_unlock(&sess->tree_conns_lock); + up_write(&sess->tree_conns_lock); err = ksmbd_tree_conn_disconnect(sess, tcon); if (err) { |
