mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-29 17:25:38 +00:00
three kernel server fixes
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmdi9NcACgkQiiy9cAdy T1EBZwv+JAGDnHiDVm4FuYg4Q0jNHjmSoJ4HkiSNSB/hKtdmA9q6xHJ76Nfrbzig 1EczCe9vAf5i9yYs4acPTT0MOK9lCyarFCYY02Dk3+/JPuyFLC5VkjplvryMGeXm 9Py07XSIFcx3EZ1Ws597OMVvTtdTzRp8EXGt6xoMmqgQhma7ggSgvXCmoC4nCf/S I2CMGx3ieeF5aPiosf8YEAjn4+MZJr4CI5hut5XZYgxND27QiB5gdPMSiHReANyi hBF8u2mwyayztlEkknmU/7TMSwJiO3zsCMLU/wECJaZgDBb5LcuWS0f9BmI8eCgj 6gk+aX6aQ6Xnx0rNdl5ezq/lQ2/j6hv2e542KQYZwX9d8wKQbSye/OLvpGxlTY6i lir2XP1W1zVAz2mAhbOw9PbAKlI24cHZamGWhGp3mkMdNddslYxJ+iAKnX6z0cv+ KkPEWET4/uyTySygBPnAOMfhTzqMiuwvPswwjYr3TXugQhArnPtOoj1lVLXPArFx CqJMrnAy =vUtk -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
466b2d40f6
@ -70,7 +70,6 @@ struct ksmbd_conn *ksmbd_conn_alloc(void)
|
||||
atomic_set(&conn->req_running, 0);
|
||||
atomic_set(&conn->r_count, 0);
|
||||
atomic_set(&conn->refcnt, 1);
|
||||
atomic_set(&conn->mux_smb_requests, 0);
|
||||
conn->total_credits = 1;
|
||||
conn->outstanding_credits = 0;
|
||||
|
||||
@ -120,8 +119,8 @@ void ksmbd_conn_enqueue_request(struct ksmbd_work *work)
|
||||
if (conn->ops->get_cmd_val(work) != SMB2_CANCEL_HE)
|
||||
requests_queue = &conn->requests;
|
||||
|
||||
atomic_inc(&conn->req_running);
|
||||
if (requests_queue) {
|
||||
atomic_inc(&conn->req_running);
|
||||
spin_lock(&conn->request_lock);
|
||||
list_add_tail(&work->request_entry, requests_queue);
|
||||
spin_unlock(&conn->request_lock);
|
||||
@ -132,11 +131,14 @@ void ksmbd_conn_try_dequeue_request(struct ksmbd_work *work)
|
||||
{
|
||||
struct ksmbd_conn *conn = work->conn;
|
||||
|
||||
atomic_dec(&conn->req_running);
|
||||
if (waitqueue_active(&conn->req_running_q))
|
||||
wake_up(&conn->req_running_q);
|
||||
|
||||
if (list_empty(&work->request_entry) &&
|
||||
list_empty(&work->async_request_entry))
|
||||
return;
|
||||
|
||||
atomic_dec(&conn->req_running);
|
||||
spin_lock(&conn->request_lock);
|
||||
list_del_init(&work->request_entry);
|
||||
spin_unlock(&conn->request_lock);
|
||||
@ -308,7 +310,7 @@ int ksmbd_conn_handler_loop(void *p)
|
||||
{
|
||||
struct ksmbd_conn *conn = (struct ksmbd_conn *)p;
|
||||
struct ksmbd_transport *t = conn->transport;
|
||||
unsigned int pdu_size, max_allowed_pdu_size;
|
||||
unsigned int pdu_size, max_allowed_pdu_size, max_req;
|
||||
char hdr_buf[4] = {0,};
|
||||
int size;
|
||||
|
||||
@ -318,6 +320,7 @@ int ksmbd_conn_handler_loop(void *p)
|
||||
if (t->ops->prepare && t->ops->prepare(t))
|
||||
goto out;
|
||||
|
||||
max_req = server_conf.max_inflight_req;
|
||||
conn->last_active = jiffies;
|
||||
set_freezable();
|
||||
while (ksmbd_conn_alive(conn)) {
|
||||
@ -327,6 +330,13 @@ int ksmbd_conn_handler_loop(void *p)
|
||||
kvfree(conn->request_buf);
|
||||
conn->request_buf = NULL;
|
||||
|
||||
recheck:
|
||||
if (atomic_read(&conn->req_running) + 1 > max_req) {
|
||||
wait_event_interruptible(conn->req_running_q,
|
||||
atomic_read(&conn->req_running) < max_req);
|
||||
goto recheck;
|
||||
}
|
||||
|
||||
size = t->ops->read(t, hdr_buf, sizeof(hdr_buf), -1);
|
||||
if (size != sizeof(hdr_buf))
|
||||
break;
|
||||
|
@ -107,7 +107,6 @@ struct ksmbd_conn {
|
||||
__le16 signing_algorithm;
|
||||
bool binding;
|
||||
atomic_t refcnt;
|
||||
atomic_t mux_smb_requests;
|
||||
};
|
||||
|
||||
struct ksmbd_conn_ops {
|
||||
|
@ -270,7 +270,6 @@ static void handle_ksmbd_work(struct work_struct *wk)
|
||||
|
||||
ksmbd_conn_try_dequeue_request(work);
|
||||
ksmbd_free_work_struct(work);
|
||||
atomic_dec(&conn->mux_smb_requests);
|
||||
/*
|
||||
* Checking waitqueue to dropping pending requests on
|
||||
* disconnection. waitqueue_active is safe because it
|
||||
@ -300,11 +299,6 @@ static int queue_ksmbd_work(struct ksmbd_conn *conn)
|
||||
if (err)
|
||||
return 0;
|
||||
|
||||
if (atomic_inc_return(&conn->mux_smb_requests) >= conn->vals->max_credits) {
|
||||
atomic_dec_return(&conn->mux_smb_requests);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
work = ksmbd_alloc_work_struct();
|
||||
if (!work) {
|
||||
pr_err("allocation for work failed\n");
|
||||
@ -367,6 +361,7 @@ static int server_conf_init(void)
|
||||
server_conf.auth_mechs |= KSMBD_AUTH_KRB5 |
|
||||
KSMBD_AUTH_MSKRB5;
|
||||
#endif
|
||||
server_conf.max_inflight_req = SMB2_MAX_CREDITS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,7 @@ struct ksmbd_server_config {
|
||||
struct smb_sid domain_sid;
|
||||
unsigned int auth_mechs;
|
||||
unsigned int max_connections;
|
||||
unsigned int max_inflight_req;
|
||||
|
||||
char *conf[SERVER_CONF_WORK_GROUP + 1];
|
||||
struct task_struct *dh_task;
|
||||
|
@ -1097,6 +1097,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
|
||||
return rc;
|
||||
}
|
||||
|
||||
ksmbd_conn_lock(conn);
|
||||
smb2_buf_len = get_rfc1002_len(work->request_buf);
|
||||
smb2_neg_size = offsetof(struct smb2_negotiate_req, Dialects);
|
||||
if (smb2_neg_size > smb2_buf_len) {
|
||||
@ -1247,6 +1248,7 @@ int smb2_handle_negotiate(struct ksmbd_work *work)
|
||||
ksmbd_conn_set_need_negotiate(conn);
|
||||
|
||||
err_out:
|
||||
ksmbd_conn_unlock(conn);
|
||||
if (rc)
|
||||
rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
|
@ -319,8 +319,11 @@ static int ipc_server_config_on_startup(struct ksmbd_startup_request *req)
|
||||
init_smb2_max_write_size(req->smb2_max_write);
|
||||
if (req->smb2_max_trans)
|
||||
init_smb2_max_trans_size(req->smb2_max_trans);
|
||||
if (req->smb2_max_credits)
|
||||
if (req->smb2_max_credits) {
|
||||
init_smb2_max_credits(req->smb2_max_credits);
|
||||
server_conf.max_inflight_req =
|
||||
req->smb2_max_credits;
|
||||
}
|
||||
if (req->smbd_max_io_size)
|
||||
init_smbd_max_io_size(req->smbd_max_io_size);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user