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;
* 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;
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);
/**
* 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;
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)
} 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;
}
}
* 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,