Loading fs/smb/server/connection.c +11 −12 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ static DEFINE_MUTEX(init_lock); static struct ksmbd_conn_ops default_conn_ops; LIST_HEAD(conn_list); DEFINE_HASHTABLE(conn_list, CONN_HASH_BITS); DECLARE_RWSEM(conn_list_lock); /** Loading @@ -33,7 +33,7 @@ DECLARE_RWSEM(conn_list_lock); void ksmbd_conn_free(struct ksmbd_conn *conn) { down_write(&conn_list_lock); list_del(&conn->conns_list); hash_del(&conn->hlist); up_write(&conn_list_lock); xa_destroy(&conn->sessions); Loading Loading @@ -77,7 +77,6 @@ struct ksmbd_conn *ksmbd_conn_alloc(void) init_waitqueue_head(&conn->req_running_q); init_waitqueue_head(&conn->r_count_q); INIT_LIST_HEAD(&conn->conns_list); INIT_LIST_HEAD(&conn->requests); INIT_LIST_HEAD(&conn->async_requests); spin_lock_init(&conn->request_lock); Loading @@ -90,19 +89,17 @@ struct ksmbd_conn *ksmbd_conn_alloc(void) init_rwsem(&conn->session_lock); down_write(&conn_list_lock); list_add(&conn->conns_list, &conn_list); up_write(&conn_list_lock); return conn; } bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c) { struct ksmbd_conn *t; int bkt; bool ret = false; down_read(&conn_list_lock); list_for_each_entry(t, &conn_list, conns_list) { hash_for_each(conn_list, bkt, t, hlist) { if (memcmp(t->ClientGUID, c->ClientGUID, SMB2_CLIENT_GUID_SIZE)) continue; Loading Loading @@ -163,9 +160,10 @@ void ksmbd_conn_unlock(struct ksmbd_conn *conn) void ksmbd_all_conn_set_status(u64 sess_id, u32 status) { struct ksmbd_conn *conn; int bkt; down_read(&conn_list_lock); list_for_each_entry(conn, &conn_list, conns_list) { hash_for_each(conn_list, bkt, conn, hlist) { if (conn->binding || xa_load(&conn->sessions, sess_id)) WRITE_ONCE(conn->status, status); } Loading @@ -181,14 +179,14 @@ int ksmbd_conn_wait_idle_sess_id(struct ksmbd_conn *curr_conn, u64 sess_id) { struct ksmbd_conn *conn; int rc, retry_count = 0, max_timeout = 120; int rcount = 1; int rcount = 1, bkt; retry_idle: if (retry_count >= max_timeout) return -EIO; down_read(&conn_list_lock); list_for_each_entry(conn, &conn_list, conns_list) { hash_for_each(conn_list, bkt, conn, hlist) { if (conn->binding || xa_load(&conn->sessions, sess_id)) { if (conn == curr_conn) rcount = 2; Loading Loading @@ -480,10 +478,11 @@ static void stop_sessions(void) { struct ksmbd_conn *conn; struct ksmbd_transport *t; int bkt; again: down_read(&conn_list_lock); list_for_each_entry(conn, &conn_list, conns_list) { hash_for_each(conn_list, bkt, conn, hlist) { t = conn->transport; ksmbd_conn_set_exiting(conn); if (t->ops->shutdown) { Loading @@ -494,7 +493,7 @@ static void stop_sessions(void) } up_read(&conn_list_lock); if (!list_empty(&conn_list)) { if (!hash_empty(conn_list)) { msleep(100); goto again; } Loading fs/smb/server/connection.h +4 −2 Original line number Diff line number Diff line Loading @@ -54,11 +54,12 @@ struct ksmbd_conn { u8 inet6_addr[16]; #endif }; unsigned int inet_hash; char *request_buf; struct ksmbd_transport *transport; struct nls_table *local_nls; struct unicode_map *um; struct list_head conns_list; struct hlist_node hlist; struct rw_semaphore session_lock; /* smb session 1 per user */ struct xarray sessions; Loading Loading @@ -153,7 +154,8 @@ struct ksmbd_transport { #define KSMBD_TCP_SEND_TIMEOUT (5 * HZ) #define KSMBD_TCP_PEER_SOCKADDR(c) ((struct sockaddr *)&((c)->peer_addr)) extern struct list_head conn_list; #define CONN_HASH_BITS 12 extern DECLARE_HASHTABLE(conn_list, CONN_HASH_BITS); extern struct rw_semaphore conn_list_lock; bool ksmbd_conn_alive(struct ksmbd_conn *conn); Loading fs/smb/server/smb2pdu.c +2 −2 Original line number Diff line number Diff line Loading @@ -7362,7 +7362,7 @@ int smb2_lock(struct ksmbd_work *work) int nolock = 0; LIST_HEAD(lock_list); LIST_HEAD(rollback_list); int prior_lock = 0; int prior_lock = 0, bkt; WORK_BUFFERS(work, req, rsp); Loading Loading @@ -7472,7 +7472,7 @@ int smb2_lock(struct ksmbd_work *work) nolock = 1; /* check locks in connection list */ down_read(&conn_list_lock); list_for_each_entry(conn, &conn_list, conns_list) { hash_for_each(conn_list, bkt, conn, hlist) { spin_lock(&conn->llist_lock); list_for_each_entry_safe(cmp_lock, tmp2, &conn->lock_list, clist) { if (file_inode(cmp_lock->fl->c.flc_file) != Loading fs/smb/server/transport_rdma.c +5 −0 Original line number Diff line number Diff line Loading @@ -425,6 +425,11 @@ static struct smb_direct_transport *alloc_transport(struct rdma_cm_id *cm_id) conn = ksmbd_conn_alloc(); if (!conn) goto err; down_write(&conn_list_lock); hash_add(conn_list, &conn->hlist, 0); up_write(&conn_list_lock); conn->transport = KSMBD_TRANS(t); KSMBD_TRANS(t)->conn = conn; KSMBD_TRANS(t)->ops = &ksmbd_smb_direct_transport_ops; Loading fs/smb/server/transport_tcp.c +21 −4 Original line number Diff line number Diff line Loading @@ -86,13 +86,21 @@ static struct tcp_transport *alloc_transport(struct socket *client_sk) } #if IS_ENABLED(CONFIG_IPV6) if (client_sk->sk->sk_family == AF_INET6) if (client_sk->sk->sk_family == AF_INET6) { memcpy(&conn->inet6_addr, &client_sk->sk->sk_v6_daddr, 16); else conn->inet_hash = ipv6_addr_hash(&client_sk->sk->sk_v6_daddr); } else { conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr; conn->inet_hash = ipv4_addr_hash(inet_sk(client_sk->sk)->inet_daddr); } #else conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr; conn->inet_hash = ipv4_addr_hash(inet_sk(client_sk->sk)->inet_daddr); #endif down_write(&conn_list_lock); hash_add(conn_list, &conn->hlist, conn->inet_hash); up_write(&conn_list_lock); conn->transport = KSMBD_TRANS(t); KSMBD_TRANS(t)->conn = conn; KSMBD_TRANS(t)->ops = &ksmbd_tcp_transport_ops; Loading Loading @@ -224,7 +232,7 @@ static int ksmbd_kthread_fn(void *p) struct socket *client_sk = NULL; struct interface *iface = (struct interface *)p; struct ksmbd_conn *conn; int ret; int ret, inet_hash; unsigned int max_ip_conns; while (!kthread_should_stop()) { Loading @@ -249,9 +257,18 @@ static int ksmbd_kthread_fn(void *p) /* * Limits repeated connections from clients with the same IP. */ #if IS_ENABLED(CONFIG_IPV6) if (client_sk->sk->sk_family == AF_INET6) inet_hash = ipv6_addr_hash(&client_sk->sk->sk_v6_daddr); else inet_hash = ipv4_addr_hash(inet_sk(client_sk->sk)->inet_daddr); #else inet_hash = ipv4_addr_hash(inet_sk(client_sk->sk)->inet_daddr); #endif max_ip_conns = 0; down_read(&conn_list_lock); list_for_each_entry(conn, &conn_list, conns_list) { hash_for_each_possible(conn_list, conn, hlist, inet_hash) { #if IS_ENABLED(CONFIG_IPV6) if (client_sk->sk->sk_family == AF_INET6) { if (memcmp(&client_sk->sk->sk_v6_daddr, Loading Loading
fs/smb/server/connection.c +11 −12 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ static DEFINE_MUTEX(init_lock); static struct ksmbd_conn_ops default_conn_ops; LIST_HEAD(conn_list); DEFINE_HASHTABLE(conn_list, CONN_HASH_BITS); DECLARE_RWSEM(conn_list_lock); /** Loading @@ -33,7 +33,7 @@ DECLARE_RWSEM(conn_list_lock); void ksmbd_conn_free(struct ksmbd_conn *conn) { down_write(&conn_list_lock); list_del(&conn->conns_list); hash_del(&conn->hlist); up_write(&conn_list_lock); xa_destroy(&conn->sessions); Loading Loading @@ -77,7 +77,6 @@ struct ksmbd_conn *ksmbd_conn_alloc(void) init_waitqueue_head(&conn->req_running_q); init_waitqueue_head(&conn->r_count_q); INIT_LIST_HEAD(&conn->conns_list); INIT_LIST_HEAD(&conn->requests); INIT_LIST_HEAD(&conn->async_requests); spin_lock_init(&conn->request_lock); Loading @@ -90,19 +89,17 @@ struct ksmbd_conn *ksmbd_conn_alloc(void) init_rwsem(&conn->session_lock); down_write(&conn_list_lock); list_add(&conn->conns_list, &conn_list); up_write(&conn_list_lock); return conn; } bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c) { struct ksmbd_conn *t; int bkt; bool ret = false; down_read(&conn_list_lock); list_for_each_entry(t, &conn_list, conns_list) { hash_for_each(conn_list, bkt, t, hlist) { if (memcmp(t->ClientGUID, c->ClientGUID, SMB2_CLIENT_GUID_SIZE)) continue; Loading Loading @@ -163,9 +160,10 @@ void ksmbd_conn_unlock(struct ksmbd_conn *conn) void ksmbd_all_conn_set_status(u64 sess_id, u32 status) { struct ksmbd_conn *conn; int bkt; down_read(&conn_list_lock); list_for_each_entry(conn, &conn_list, conns_list) { hash_for_each(conn_list, bkt, conn, hlist) { if (conn->binding || xa_load(&conn->sessions, sess_id)) WRITE_ONCE(conn->status, status); } Loading @@ -181,14 +179,14 @@ int ksmbd_conn_wait_idle_sess_id(struct ksmbd_conn *curr_conn, u64 sess_id) { struct ksmbd_conn *conn; int rc, retry_count = 0, max_timeout = 120; int rcount = 1; int rcount = 1, bkt; retry_idle: if (retry_count >= max_timeout) return -EIO; down_read(&conn_list_lock); list_for_each_entry(conn, &conn_list, conns_list) { hash_for_each(conn_list, bkt, conn, hlist) { if (conn->binding || xa_load(&conn->sessions, sess_id)) { if (conn == curr_conn) rcount = 2; Loading Loading @@ -480,10 +478,11 @@ static void stop_sessions(void) { struct ksmbd_conn *conn; struct ksmbd_transport *t; int bkt; again: down_read(&conn_list_lock); list_for_each_entry(conn, &conn_list, conns_list) { hash_for_each(conn_list, bkt, conn, hlist) { t = conn->transport; ksmbd_conn_set_exiting(conn); if (t->ops->shutdown) { Loading @@ -494,7 +493,7 @@ static void stop_sessions(void) } up_read(&conn_list_lock); if (!list_empty(&conn_list)) { if (!hash_empty(conn_list)) { msleep(100); goto again; } Loading
fs/smb/server/connection.h +4 −2 Original line number Diff line number Diff line Loading @@ -54,11 +54,12 @@ struct ksmbd_conn { u8 inet6_addr[16]; #endif }; unsigned int inet_hash; char *request_buf; struct ksmbd_transport *transport; struct nls_table *local_nls; struct unicode_map *um; struct list_head conns_list; struct hlist_node hlist; struct rw_semaphore session_lock; /* smb session 1 per user */ struct xarray sessions; Loading Loading @@ -153,7 +154,8 @@ struct ksmbd_transport { #define KSMBD_TCP_SEND_TIMEOUT (5 * HZ) #define KSMBD_TCP_PEER_SOCKADDR(c) ((struct sockaddr *)&((c)->peer_addr)) extern struct list_head conn_list; #define CONN_HASH_BITS 12 extern DECLARE_HASHTABLE(conn_list, CONN_HASH_BITS); extern struct rw_semaphore conn_list_lock; bool ksmbd_conn_alive(struct ksmbd_conn *conn); Loading
fs/smb/server/smb2pdu.c +2 −2 Original line number Diff line number Diff line Loading @@ -7362,7 +7362,7 @@ int smb2_lock(struct ksmbd_work *work) int nolock = 0; LIST_HEAD(lock_list); LIST_HEAD(rollback_list); int prior_lock = 0; int prior_lock = 0, bkt; WORK_BUFFERS(work, req, rsp); Loading Loading @@ -7472,7 +7472,7 @@ int smb2_lock(struct ksmbd_work *work) nolock = 1; /* check locks in connection list */ down_read(&conn_list_lock); list_for_each_entry(conn, &conn_list, conns_list) { hash_for_each(conn_list, bkt, conn, hlist) { spin_lock(&conn->llist_lock); list_for_each_entry_safe(cmp_lock, tmp2, &conn->lock_list, clist) { if (file_inode(cmp_lock->fl->c.flc_file) != Loading
fs/smb/server/transport_rdma.c +5 −0 Original line number Diff line number Diff line Loading @@ -425,6 +425,11 @@ static struct smb_direct_transport *alloc_transport(struct rdma_cm_id *cm_id) conn = ksmbd_conn_alloc(); if (!conn) goto err; down_write(&conn_list_lock); hash_add(conn_list, &conn->hlist, 0); up_write(&conn_list_lock); conn->transport = KSMBD_TRANS(t); KSMBD_TRANS(t)->conn = conn; KSMBD_TRANS(t)->ops = &ksmbd_smb_direct_transport_ops; Loading
fs/smb/server/transport_tcp.c +21 −4 Original line number Diff line number Diff line Loading @@ -86,13 +86,21 @@ static struct tcp_transport *alloc_transport(struct socket *client_sk) } #if IS_ENABLED(CONFIG_IPV6) if (client_sk->sk->sk_family == AF_INET6) if (client_sk->sk->sk_family == AF_INET6) { memcpy(&conn->inet6_addr, &client_sk->sk->sk_v6_daddr, 16); else conn->inet_hash = ipv6_addr_hash(&client_sk->sk->sk_v6_daddr); } else { conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr; conn->inet_hash = ipv4_addr_hash(inet_sk(client_sk->sk)->inet_daddr); } #else conn->inet_addr = inet_sk(client_sk->sk)->inet_daddr; conn->inet_hash = ipv4_addr_hash(inet_sk(client_sk->sk)->inet_daddr); #endif down_write(&conn_list_lock); hash_add(conn_list, &conn->hlist, conn->inet_hash); up_write(&conn_list_lock); conn->transport = KSMBD_TRANS(t); KSMBD_TRANS(t)->conn = conn; KSMBD_TRANS(t)->ops = &ksmbd_tcp_transport_ops; Loading Loading @@ -224,7 +232,7 @@ static int ksmbd_kthread_fn(void *p) struct socket *client_sk = NULL; struct interface *iface = (struct interface *)p; struct ksmbd_conn *conn; int ret; int ret, inet_hash; unsigned int max_ip_conns; while (!kthread_should_stop()) { Loading @@ -249,9 +257,18 @@ static int ksmbd_kthread_fn(void *p) /* * Limits repeated connections from clients with the same IP. */ #if IS_ENABLED(CONFIG_IPV6) if (client_sk->sk->sk_family == AF_INET6) inet_hash = ipv6_addr_hash(&client_sk->sk->sk_v6_daddr); else inet_hash = ipv4_addr_hash(inet_sk(client_sk->sk)->inet_daddr); #else inet_hash = ipv4_addr_hash(inet_sk(client_sk->sk)->inet_daddr); #endif max_ip_conns = 0; down_read(&conn_list_lock); list_for_each_entry(conn, &conn_list, conns_list) { hash_for_each_possible(conn_list, conn, hlist, inet_hash) { #if IS_ENABLED(CONFIG_IPV6) if (client_sk->sk->sk_family == AF_INET6) { if (memcmp(&client_sk->sk->sk_v6_daddr, Loading