mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-16 01:04:08 +08:00
ksmbd: don't terminate inactive sessions after a few seconds
Steve reported that inactive sessions are terminated after a few seconds. ksmbd terminate when receiving -EAGAIN error from kernel_recvmsg(). -EAGAIN means there is no data available in timeout. So ksmbd should keep connection with unlimited retries instead of terminating inactive sessions. Cc: stable@vger.kernel.org Reported-by: Steve French <stfrench@microsoft.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
2624b44554
commit
be6f42fad5
@ -298,7 +298,7 @@ int ksmbd_conn_handler_loop(void *p)
|
||||
kvfree(conn->request_buf);
|
||||
conn->request_buf = NULL;
|
||||
|
||||
size = t->ops->read(t, hdr_buf, sizeof(hdr_buf));
|
||||
size = t->ops->read(t, hdr_buf, sizeof(hdr_buf), -1);
|
||||
if (size != sizeof(hdr_buf))
|
||||
break;
|
||||
|
||||
@ -344,7 +344,7 @@ int ksmbd_conn_handler_loop(void *p)
|
||||
* We already read 4 bytes to find out PDU size, now
|
||||
* read in PDU
|
||||
*/
|
||||
size = t->ops->read(t, conn->request_buf + 4, pdu_size);
|
||||
size = t->ops->read(t, conn->request_buf + 4, pdu_size, 2);
|
||||
if (size < 0) {
|
||||
pr_err("sock_read failed: %d\n", size);
|
||||
break;
|
||||
|
@ -114,7 +114,8 @@ struct ksmbd_transport_ops {
|
||||
int (*prepare)(struct ksmbd_transport *t);
|
||||
void (*disconnect)(struct ksmbd_transport *t);
|
||||
void (*shutdown)(struct ksmbd_transport *t);
|
||||
int (*read)(struct ksmbd_transport *t, char *buf, unsigned int size);
|
||||
int (*read)(struct ksmbd_transport *t, char *buf,
|
||||
unsigned int size, int max_retries);
|
||||
int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov,
|
||||
int size, bool need_invalidate_rkey,
|
||||
unsigned int remote_key);
|
||||
|
@ -670,7 +670,7 @@ static int smb_direct_post_recv(struct smb_direct_transport *t,
|
||||
}
|
||||
|
||||
static int smb_direct_read(struct ksmbd_transport *t, char *buf,
|
||||
unsigned int size)
|
||||
unsigned int size, int unused)
|
||||
{
|
||||
struct smb_direct_recvmsg *recvmsg;
|
||||
struct smb_direct_data_transfer *data_transfer;
|
||||
|
@ -291,16 +291,18 @@ static int ksmbd_tcp_run_kthread(struct interface *iface)
|
||||
|
||||
/**
|
||||
* ksmbd_tcp_readv() - read data from socket in given iovec
|
||||
* @t: TCP transport instance
|
||||
* @iov_orig: base IO vector
|
||||
* @nr_segs: number of segments in base iov
|
||||
* @to_read: number of bytes to read from socket
|
||||
* @t: TCP transport instance
|
||||
* @iov_orig: base IO vector
|
||||
* @nr_segs: number of segments in base iov
|
||||
* @to_read: number of bytes to read from socket
|
||||
* @max_retries: maximum retry count
|
||||
*
|
||||
* Return: on success return number of bytes read from socket,
|
||||
* otherwise return error number
|
||||
*/
|
||||
static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
|
||||
unsigned int nr_segs, unsigned int to_read)
|
||||
unsigned int nr_segs, unsigned int to_read,
|
||||
int max_retries)
|
||||
{
|
||||
int length = 0;
|
||||
int total_read;
|
||||
@ -308,7 +310,6 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
|
||||
struct msghdr ksmbd_msg;
|
||||
struct kvec *iov;
|
||||
struct ksmbd_conn *conn = KSMBD_TRANS(t)->conn;
|
||||
int max_retry = 2;
|
||||
|
||||
iov = get_conn_iovec(t, nr_segs);
|
||||
if (!iov)
|
||||
@ -335,14 +336,23 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
|
||||
} else if (conn->status == KSMBD_SESS_NEED_RECONNECT) {
|
||||
total_read = -EAGAIN;
|
||||
break;
|
||||
} else if ((length == -ERESTARTSYS || length == -EAGAIN) &&
|
||||
max_retry) {
|
||||
} else if (length == -ERESTARTSYS || length == -EAGAIN) {
|
||||
/*
|
||||
* If max_retries is negative, Allow unlimited
|
||||
* retries to keep connection with inactive sessions.
|
||||
*/
|
||||
if (max_retries == 0) {
|
||||
total_read = length;
|
||||
break;
|
||||
} else if (max_retries > 0) {
|
||||
max_retries--;
|
||||
}
|
||||
|
||||
usleep_range(1000, 2000);
|
||||
length = 0;
|
||||
max_retry--;
|
||||
continue;
|
||||
} else if (length <= 0) {
|
||||
total_read = -EAGAIN;
|
||||
total_read = length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -358,14 +368,15 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
|
||||
* Return: on success return number of bytes read from socket,
|
||||
* otherwise return error number
|
||||
*/
|
||||
static int ksmbd_tcp_read(struct ksmbd_transport *t, char *buf, unsigned int to_read)
|
||||
static int ksmbd_tcp_read(struct ksmbd_transport *t, char *buf,
|
||||
unsigned int to_read, int max_retries)
|
||||
{
|
||||
struct kvec iov;
|
||||
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = to_read;
|
||||
|
||||
return ksmbd_tcp_readv(TCP_TRANS(t), &iov, 1, to_read);
|
||||
return ksmbd_tcp_readv(TCP_TRANS(t), &iov, 1, to_read, max_retries);
|
||||
}
|
||||
|
||||
static int ksmbd_tcp_writev(struct ksmbd_transport *t, struct kvec *iov,
|
||||
|
Loading…
Reference in New Issue
Block a user