summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2008-10-22 13:12:36 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-10-22 13:36:05 -0400
commit1cd9cd161c89f569b90583b7797bd972c3bf0cff (patch)
tree1b2f43ddc4d22089de09b949442f4b46663e3949
parent107e0008dfb8bd6366bc8827f5bbbc0c1f795d2d (diff)
downloadlinux-1cd9cd161c89f569b90583b7797bd972c3bf0cff.tar.bz2
NFSD: Fix BUG during NFSD shutdown processing
The Linux NFS server can be started via a user-space write to /proc/fs/nfs/threads or to /proc/fs/nfs/portlist. In the first case, all default listeners are started (both UDP and TCP). In the second, a listener is started only for one specified transport. The NFS server has to make sure lockd stays up until the last listener transport goes away. To support both start-up interfaces, it should do one lockd_up() for each NFSD listener. The nfsd_init_socks() function used to do one lockd_up() call for each svc_create_xprt(). Recently commit 26a414092353590ceaa5955bcb53f863d6ea7549 mistakenly changed nfsd_init_socks() to do only one lockd_up() call even though it still does two svc_create_xprt() calls. The end result is a lockd_down() BUG during NFSD shutdown processing because nfsd_last_threads() does a lockd_down() call for each entry on the sv_permsocks list, but the start-up code doesn't do a matching number of lockd_up() calls. Add a second lockd_up() in nfsd_init_socks() to make sure the number of lockd_up() calls matches the number of entries on the NFS servers's sv_permsocks list. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
-rw-r--r--fs/nfsd/nfssvc.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 59eeb46f82c5..07e4f5d7baa8 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -249,6 +249,10 @@ static int nfsd_init_socks(int port)
if (error < 0)
return error;
+ error = lockd_up();
+ if (error < 0)
+ return error;
+
error = svc_create_xprt(nfsd_serv, "tcp", port,
SVC_SOCK_DEFAULTS);
if (error < 0)