Skip to content

Commit be6f42f

Browse files
namjaejeonsmfrench
authored andcommitted
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: [email protected] Reported-by: Steve French <[email protected]> Signed-off-by: Namjae Jeon <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 2624b44 commit be6f42f

File tree

4 files changed

+28
-16
lines changed

4 files changed

+28
-16
lines changed

fs/ksmbd/connection.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ int ksmbd_conn_handler_loop(void *p)
298298
kvfree(conn->request_buf);
299299
conn->request_buf = NULL;
300300

301-
size = t->ops->read(t, hdr_buf, sizeof(hdr_buf));
301+
size = t->ops->read(t, hdr_buf, sizeof(hdr_buf), -1);
302302
if (size != sizeof(hdr_buf))
303303
break;
304304

@@ -344,7 +344,7 @@ int ksmbd_conn_handler_loop(void *p)
344344
* We already read 4 bytes to find out PDU size, now
345345
* read in PDU
346346
*/
347-
size = t->ops->read(t, conn->request_buf + 4, pdu_size);
347+
size = t->ops->read(t, conn->request_buf + 4, pdu_size, 2);
348348
if (size < 0) {
349349
pr_err("sock_read failed: %d\n", size);
350350
break;

fs/ksmbd/connection.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ struct ksmbd_transport_ops {
114114
int (*prepare)(struct ksmbd_transport *t);
115115
void (*disconnect)(struct ksmbd_transport *t);
116116
void (*shutdown)(struct ksmbd_transport *t);
117-
int (*read)(struct ksmbd_transport *t, char *buf, unsigned int size);
117+
int (*read)(struct ksmbd_transport *t, char *buf,
118+
unsigned int size, int max_retries);
118119
int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov,
119120
int size, bool need_invalidate_rkey,
120121
unsigned int remote_key);

fs/ksmbd/transport_rdma.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ static int smb_direct_post_recv(struct smb_direct_transport *t,
670670
}
671671

672672
static int smb_direct_read(struct ksmbd_transport *t, char *buf,
673-
unsigned int size)
673+
unsigned int size, int unused)
674674
{
675675
struct smb_direct_recvmsg *recvmsg;
676676
struct smb_direct_data_transfer *data_transfer;

fs/ksmbd/transport_tcp.c

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -291,24 +291,25 @@ static int ksmbd_tcp_run_kthread(struct interface *iface)
291291

292292
/**
293293
* ksmbd_tcp_readv() - read data from socket in given iovec
294-
* @t: TCP transport instance
295-
* @iov_orig: base IO vector
296-
* @nr_segs: number of segments in base iov
297-
* @to_read: number of bytes to read from socket
294+
* @t: TCP transport instance
295+
* @iov_orig: base IO vector
296+
* @nr_segs: number of segments in base iov
297+
* @to_read: number of bytes to read from socket
298+
* @max_retries: maximum retry count
298299
*
299300
* Return: on success return number of bytes read from socket,
300301
* otherwise return error number
301302
*/
302303
static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
303-
unsigned int nr_segs, unsigned int to_read)
304+
unsigned int nr_segs, unsigned int to_read,
305+
int max_retries)
304306
{
305307
int length = 0;
306308
int total_read;
307309
unsigned int segs;
308310
struct msghdr ksmbd_msg;
309311
struct kvec *iov;
310312
struct ksmbd_conn *conn = KSMBD_TRANS(t)->conn;
311-
int max_retry = 2;
312313

313314
iov = get_conn_iovec(t, nr_segs);
314315
if (!iov)
@@ -335,14 +336,23 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
335336
} else if (conn->status == KSMBD_SESS_NEED_RECONNECT) {
336337
total_read = -EAGAIN;
337338
break;
338-
} else if ((length == -ERESTARTSYS || length == -EAGAIN) &&
339-
max_retry) {
339+
} else if (length == -ERESTARTSYS || length == -EAGAIN) {
340+
/*
341+
* If max_retries is negative, Allow unlimited
342+
* retries to keep connection with inactive sessions.
343+
*/
344+
if (max_retries == 0) {
345+
total_read = length;
346+
break;
347+
} else if (max_retries > 0) {
348+
max_retries--;
349+
}
350+
340351
usleep_range(1000, 2000);
341352
length = 0;
342-
max_retry--;
343353
continue;
344354
} else if (length <= 0) {
345-
total_read = -EAGAIN;
355+
total_read = length;
346356
break;
347357
}
348358
}
@@ -358,14 +368,15 @@ static int ksmbd_tcp_readv(struct tcp_transport *t, struct kvec *iov_orig,
358368
* Return: on success return number of bytes read from socket,
359369
* otherwise return error number
360370
*/
361-
static int ksmbd_tcp_read(struct ksmbd_transport *t, char *buf, unsigned int to_read)
371+
static int ksmbd_tcp_read(struct ksmbd_transport *t, char *buf,
372+
unsigned int to_read, int max_retries)
362373
{
363374
struct kvec iov;
364375

365376
iov.iov_base = buf;
366377
iov.iov_len = to_read;
367378

368-
return ksmbd_tcp_readv(TCP_TRANS(t), &iov, 1, to_read);
379+
return ksmbd_tcp_readv(TCP_TRANS(t), &iov, 1, to_read, max_retries);
369380
}
370381

371382
static int ksmbd_tcp_writev(struct ksmbd_transport *t, struct kvec *iov,

0 commit comments

Comments
 (0)