Merge tag '6.2-rc5-ksmbd-server-fixes' of git://git.samba.org/ksmbd
[sfrench/cifs-2.6.git] / fs / ksmbd / transport_tcp.c
index 4c6bd0b699791321eda9ab9b82d98be3a5aa7ada..603893fd87f57d632107258052df2b79407db3ae 100644 (file)
@@ -15,6 +15,8 @@
 #define IFACE_STATE_DOWN               BIT(0)
 #define IFACE_STATE_CONFIGURED         BIT(1)
 
+static atomic_t active_num_conn;
+
 struct interface {
        struct task_struct      *ksmbd_kthread;
        struct socket           *ksmbd_socket;
@@ -185,8 +187,10 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)
        struct tcp_transport *t;
 
        t = alloc_transport(client_sk);
-       if (!t)
+       if (!t) {
+               sock_release(client_sk);
                return -ENOMEM;
+       }
 
        csin = KSMBD_TCP_PEER_SOCKADDR(KSMBD_TRANS(t)->conn);
        if (kernel_getpeername(client_sk, csin) < 0) {
@@ -239,6 +243,15 @@ static int ksmbd_kthread_fn(void *p)
                        continue;
                }
 
+               if (server_conf.max_connections &&
+                   atomic_inc_return(&active_num_conn) >= server_conf.max_connections) {
+                       pr_info_ratelimited("Limit the maximum number of connections(%u)\n",
+                                           atomic_read(&active_num_conn));
+                       atomic_dec(&active_num_conn);
+                       sock_release(client_sk);
+                       continue;
+               }
+
                ksmbd_debug(CONN, "connect success: accepted new connection\n");
                client_sk->sk->sk_rcvtimeo = KSMBD_TCP_RECV_TIMEOUT;
                client_sk->sk->sk_sndtimeo = KSMBD_TCP_SEND_TIMEOUT;
@@ -368,6 +381,8 @@ static int ksmbd_tcp_writev(struct ksmbd_transport *t, struct kvec *iov,
 static void ksmbd_tcp_disconnect(struct ksmbd_transport *t)
 {
        free_transport(TCP_TRANS(t));
+       if (server_conf.max_connections)
+               atomic_dec(&active_num_conn);
 }
 
 static void tcp_destroy_socket(struct socket *ksmbd_socket)