git: db8c27f49910 - main - nfsd: fix a NFSv4.1 Linux client mount stuck in CLOSE_WAIT

Rick Macklem rmacklem at FreeBSD.org
Tue Apr 27 22:36:06 UTC 2021


The branch main has been updated by rmacklem:

URL: https://cgit.FreeBSD.org/src/commit/?id=db8c27f499105dcc9872dcc46e88bdd570c24fee

commit db8c27f499105dcc9872dcc46e88bdd570c24fee
Author:     Rick Macklem <rmacklem at FreeBSD.org>
AuthorDate: 2021-04-27 22:32:35 +0000
Commit:     Rick Macklem <rmacklem at FreeBSD.org>
CommitDate: 2021-04-27 22:32:35 +0000

    nfsd: fix a NFSv4.1 Linux client mount stuck in CLOSE_WAIT
    
    It was reported that a NFSv4.1 Linux client mount against
    a FreeBSD12 server was hung, with the TCP connection in
    CLOSE_WAIT state on the server.
    When a NFSv4.1/4.2 mount is done and the back channel is
    bound to the TCP connection, the soclose() is delayed until
    a new TCP connection is bound to the back channel, due to
    a reference count being held on the SVCXPRT structure in
    the krpc for the socket. Without the soclose() call, the socket
    will remain in CLOSE_WAIT and this somehow caused the Linux
    client to hang.
    
    This patch adds calls to soshutdown(.., SHUT_WR) that
    are performed when the server side krpc sees that the
    socket is no longer usable.  Since this can be done
    before the back channel is bound to a new TCP connection,
    it allows the TCP connection to proceed to CLOSED state.
    
    PR:     254590
    Reported by:    jbreitman at tildenparkcapital.com
    Reviewed by:    tuexen
    Comments by:    kevans
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D29526
---
 sys/rpc/svc.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/sys/rpc/svc.c b/sys/rpc/svc.c
index a059096e7b77..be0f08ebca9d 100644
--- a/sys/rpc/svc.c
+++ b/sys/rpc/svc.c
@@ -203,6 +203,8 @@ svcpool_cleanup(SVCPOOL *pool)
 		mtx_unlock(&grp->sg_lock);
 	}
 	TAILQ_FOREACH_SAFE(xprt, &cleanup, xp_link, nxprt) {
+		if (xprt->xp_socket != NULL)
+			soshutdown(xprt->xp_socket, SHUT_WR);
 		SVC_RELEASE(xprt);
 	}
 
@@ -388,6 +390,8 @@ xprt_unregister(SVCXPRT *xprt)
 	xprt_unregister_locked(xprt);
 	mtx_unlock(&grp->sg_lock);
 
+	if (xprt->xp_socket != NULL)
+		soshutdown(xprt->xp_socket, SHUT_WR);
 	SVC_RELEASE(xprt);
 }
 
@@ -1078,6 +1082,7 @@ svc_checkidle(SVCGROUP *grp)
 
 	mtx_unlock(&grp->sg_lock);
 	TAILQ_FOREACH_SAFE(xprt, &cleanup, xp_link, nxprt) {
+		soshutdown(xprt->xp_socket, SHUT_WR);
 		SVC_RELEASE(xprt);
 	}
 	mtx_lock(&grp->sg_lock);


More information about the dev-commits-src-all mailing list