Re: Need help debugging NFS issues new to 4.20 kernel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 2019-02-15 at 14:33 -0600, Jason L Tibbitts III wrote:
> > > > > > "BC" == Benjamin Coddington <bcodding@xxxxxxxxxx> writes:
> 
> BC> Hmm.. commit c443305529d1d3d3bee0d68fdd14ae89835e091f changed
> BC> xs_read_stream_reply() to return recv.copied instead of "ret" to
> BC> xprt_complete_rqst()..

That's a good thing. xprt_complete_rqst() really dislikes negative
error values.

> BC> You could try reverting that commit and see if the problem goes
> BC> away..
> 
> So patching a revert of that into 4.20.7 was beyond me, but I
> received
> some help from Jeremy Cline on IRC (in #fedora-kernel) and ended up
> with
> a patch I'll include at the end.  So far it does seem to be better,
> but
> because of secure boot annoyances I haven't been able to roll it out
> more generally.  However, it has been stable for a week on a few
> hosts
> which have been problematic with stock 4.20.6.
> 
> I will continue to test, but hopefully this helps folks to understand
> what's happening.
> 

Hmm... Does the following patch help at all?
---
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 7754aa3e434f..a1a8903ae5d0 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -404,8 +404,8 @@ xs_read_xdr_buf(struct socket *sock, struct msghdr
*msg, int flags,
 	size_t want, seek_init = seek, offset = 0;
 	ssize_t ret;
 
-	if (seek < buf->head[0].iov_len) {
-		want = min_t(size_t, count, buf->head[0].iov_len);
+	want = min_t(size_t, count, buf->head[0].iov_len);
+	if (seek < want) {
 		ret = xs_read_kvec(sock, msg, flags, &buf->head[0],
want, seek);
 		if (ret <= 0)
 			goto sock_err;
@@ -416,8 +416,8 @@ xs_read_xdr_buf(struct socket *sock, struct msghdr
*msg, int flags,
 			goto out;
 		seek = 0;
 	} else {
-		seek -= buf->head[0].iov_len;
-		offset += buf->head[0].iov_len;
+		seek -= want;
+		offset += want;
 	}
 
 	want = xs_alloc_sparse_pages(buf,
@@ -442,8 +442,8 @@ xs_read_xdr_buf(struct socket *sock, struct msghdr
*msg, int flags,
 		offset += want;
 	}
 
-	if (seek < buf->tail[0].iov_len) {
-		want = min_t(size_t, count - offset, buf-
>tail[0].iov_len);
+	want = min_t(size_t, count - offset, buf->tail[0].iov_len);
+	if (seek < want) {
 		ret = xs_read_kvec(sock, msg, flags, &buf->tail[0],
want, seek);
 		if (ret <= 0)
 			goto sock_err;
@@ -453,7 +453,7 @@ xs_read_xdr_buf(struct socket *sock, struct msghdr
*msg, int flags,
 		if (ret != want)
 			goto out;
 	} else
-		offset += buf->tail[0].iov_len;
+		offset = seek_init;
 	ret = -EMSGSIZE;
 out:
 	*read = offset - seek_init;
@@ -497,11 +497,9 @@ xs_read_stream_request(struct sock_xprt
*transport, struct msghdr *msg,
 			&read);
 	transport->recv.offset += read;
 	transport->recv.copied += read;
-	if (transport->recv.offset == transport->recv.len) {
-		if (xs_read_stream_request_done(transport))
-			msg->msg_flags |= MSG_EOR;
-		return read;
-	}
+	if (transport->recv.offset == transport->recv.len &&
+	    xs_read_stream_request_done(transport))
+		msg->msg_flags |= MSG_EOR;
 
 	switch (ret) {
 	default:
@@ -671,6 +669,8 @@ static void xs_stream_data_receive(struct sock_xprt
*transport)
 		read += ret;
 		cond_resched();
 	}
+	if (ret == -ESHUTDOWN)
+		kernel_sock_shutdown(transport->sock, SHUT_RDWR);
 out:
 	mutex_unlock(&transport->recv_mutex);
 	trace_xs_stream_read_data(&transport->xprt, ret, read);
-- 
Trond Myklebust
Linux NFS client maintainer, Hammerspace
trond.myklebust@xxxxxxxxxxxxxxx






[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux