summaryrefslogtreecommitdiff
path: root/fs/smb/server/smb2pdu.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/smb/server/smb2pdu.c')
-rw-r--r--fs/smb/server/smb2pdu.c23
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) {