Skip to content

Commit 466b2d4

Browse files
committed
Merge tag 'v6.13-rc3-ksmbd-server-fixes' of git://git.samba.org/ksmbd
Pull smb server fixes from Steve French: - Two fixes for better handling maximum outstanding requests - Fix simultaneous negotiate protocol race * tag 'v6.13-rc3-ksmbd-server-fixes' of git://git.samba.org/ksmbd: ksmbd: conn lock to serialize smb2 negotiate ksmbd: fix broken transfers when exceeding max simultaneous operations ksmbd: count all requests in req_running counter
2 parents eabcdba + fe4ed2f commit 466b2d4

File tree

6 files changed

+22
-12
lines changed

6 files changed

+22
-12
lines changed

fs/smb/server/connection.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ struct ksmbd_conn *ksmbd_conn_alloc(void)
7070
atomic_set(&conn->req_running, 0);
7171
atomic_set(&conn->r_count, 0);
7272
atomic_set(&conn->refcnt, 1);
73-
atomic_set(&conn->mux_smb_requests, 0);
7473
conn->total_credits = 1;
7574
conn->outstanding_credits = 0;
7675

@@ -120,8 +119,8 @@ void ksmbd_conn_enqueue_request(struct ksmbd_work *work)
120119
if (conn->ops->get_cmd_val(work) != SMB2_CANCEL_HE)
121120
requests_queue = &conn->requests;
122121

122+
atomic_inc(&conn->req_running);
123123
if (requests_queue) {
124-
atomic_inc(&conn->req_running);
125124
spin_lock(&conn->request_lock);
126125
list_add_tail(&work->request_entry, requests_queue);
127126
spin_unlock(&conn->request_lock);
@@ -132,11 +131,14 @@ void ksmbd_conn_try_dequeue_request(struct ksmbd_work *work)
132131
{
133132
struct ksmbd_conn *conn = work->conn;
134133

134+
atomic_dec(&conn->req_running);
135+
if (waitqueue_active(&conn->req_running_q))
136+
wake_up(&conn->req_running_q);
137+
135138
if (list_empty(&work->request_entry) &&
136139
list_empty(&work->async_request_entry))
137140
return;
138141

139-
atomic_dec(&conn->req_running);
140142
spin_lock(&conn->request_lock);
141143
list_del_init(&work->request_entry);
142144
spin_unlock(&conn->request_lock);
@@ -308,7 +310,7 @@ int ksmbd_conn_handler_loop(void *p)
308310
{
309311
struct ksmbd_conn *conn = (struct ksmbd_conn *)p;
310312
struct ksmbd_transport *t = conn->transport;
311-
unsigned int pdu_size, max_allowed_pdu_size;
313+
unsigned int pdu_size, max_allowed_pdu_size, max_req;
312314
char hdr_buf[4] = {0,};
313315
int size;
314316

@@ -318,6 +320,7 @@ int ksmbd_conn_handler_loop(void *p)
318320
if (t->ops->prepare && t->ops->prepare(t))
319321
goto out;
320322

323+
max_req = server_conf.max_inflight_req;
321324
conn->last_active = jiffies;
322325
set_freezable();
323326
while (ksmbd_conn_alive(conn)) {
@@ -327,6 +330,13 @@ int ksmbd_conn_handler_loop(void *p)
327330
kvfree(conn->request_buf);
328331
conn->request_buf = NULL;
329332

333+
recheck:
334+
if (atomic_read(&conn->req_running) + 1 > max_req) {
335+
wait_event_interruptible(conn->req_running_q,
336+
atomic_read(&conn->req_running) < max_req);
337+
goto recheck;
338+
}
339+
330340
size = t->ops->read(t, hdr_buf, sizeof(hdr_buf), -1);
331341
if (size != sizeof(hdr_buf))
332342
break;

fs/smb/server/connection.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@ struct ksmbd_conn {
107107
__le16 signing_algorithm;
108108
bool binding;
109109
atomic_t refcnt;
110-
atomic_t mux_smb_requests;
111110
};
112111

113112
struct ksmbd_conn_ops {

fs/smb/server/server.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,6 @@ static void handle_ksmbd_work(struct work_struct *wk)
270270

271271
ksmbd_conn_try_dequeue_request(work);
272272
ksmbd_free_work_struct(work);
273-
atomic_dec(&conn->mux_smb_requests);
274273
/*
275274
* Checking waitqueue to dropping pending requests on
276275
* disconnection. waitqueue_active is safe because it
@@ -300,11 +299,6 @@ static int queue_ksmbd_work(struct ksmbd_conn *conn)
300299
if (err)
301300
return 0;
302301

303-
if (atomic_inc_return(&conn->mux_smb_requests) >= conn->vals->max_credits) {
304-
atomic_dec_return(&conn->mux_smb_requests);
305-
return -ENOSPC;
306-
}
307-
308302
work = ksmbd_alloc_work_struct();
309303
if (!work) {
310304
pr_err("allocation for work failed\n");
@@ -367,6 +361,7 @@ static int server_conf_init(void)
367361
server_conf.auth_mechs |= KSMBD_AUTH_KRB5 |
368362
KSMBD_AUTH_MSKRB5;
369363
#endif
364+
server_conf.max_inflight_req = SMB2_MAX_CREDITS;
370365
return 0;
371366
}
372367

fs/smb/server/server.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct ksmbd_server_config {
4242
struct smb_sid domain_sid;
4343
unsigned int auth_mechs;
4444
unsigned int max_connections;
45+
unsigned int max_inflight_req;
4546

4647
char *conf[SERVER_CONF_WORK_GROUP + 1];
4748
struct task_struct *dh_task;

fs/smb/server/smb2pdu.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
10971097
return rc;
10981098
}
10991099

1100+
ksmbd_conn_lock(conn);
11001101
smb2_buf_len = get_rfc1002_len(work->request_buf);
11011102
smb2_neg_size = offsetof(struct smb2_negotiate_req, Dialects);
11021103
if (smb2_neg_size > smb2_buf_len) {
@@ -1247,6 +1248,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
12471248
ksmbd_conn_set_need_negotiate(conn);
12481249

12491250
err_out:
1251+
ksmbd_conn_unlock(conn);
12501252
if (rc)
12511253
rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
12521254

fs/smb/server/transport_ipc.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,11 @@ static int ipc_server_config_on_startup(struct ksmbd_startup_request *req)
319319
init_smb2_max_write_size(req->smb2_max_write);
320320
if (req->smb2_max_trans)
321321
init_smb2_max_trans_size(req->smb2_max_trans);
322-
if (req->smb2_max_credits)
322+
if (req->smb2_max_credits) {
323323
init_smb2_max_credits(req->smb2_max_credits);
324+
server_conf.max_inflight_req =
325+
req->smb2_max_credits;
326+
}
324327
if (req->smbd_max_io_size)
325328
init_smbd_max_io_size(req->smbd_max_io_size);
326329

0 commit comments

Comments
 (0)