aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd/svc.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2008-10-03 17:15:23 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-10-04 17:08:16 -0400
commit8c3916f4bdf9c8388bd70d0b399b3a43daf2087a (patch)
tree738c44f56265c6fbca20ce8c7ec8aa655ce56803 /fs/lockd/svc.c
parent9a38a83880c224c6a3fd973ac9ae30a043487f0f (diff)
NLM: Always start both UDP and TCP listeners
Commit 24e36663, which first appeared in 2.6.19, changed lockd so that the client side starts a UDP listener only if there is a UDP NFSv2/v3 mount. Its description notes: This... means that lockd will *not* listen on UDP if the only mounts are TCP mount (and nfsd hasn't started). The latter is the only one that concerns me at all - I don't know if this might be a problem with some servers. Unfortunately it is a problem for Linux itself. The rpc.statd daemon on Linux uses UDP for contacting the local lockd, no matter which protocol is used for NFS mounts. Without a local lockd UDP listener, NFSv2/v3 lock recovery from Linux NFS clients always fails. Revert parts of commit 24e36663 so lockd_up() always starts both listeners. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Cc: Neil Brown <neilb@suse.de> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/lockd/svc.c')
-rw-r--r--fs/lockd/svc.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index f013aed11533..36396fc058c5 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -189,25 +189,28 @@ lockd(void *vrqstp)
189} 189}
190 190
191/* 191/*
192 * Make any sockets that are needed but not present. 192 * Ensure there are active UDP and TCP listeners for lockd.
193 * If nlm_udpport or nlm_tcpport were set as module 193 *
194 * options, make those sockets unconditionally 194 * Even if we have only TCP NFS mounts and/or TCP NFSDs, some
195 * local services (such as rpc.statd) still require UDP, and
196 * some NFS servers do not yet support NLM over TCP.
197 *
198 * Returns zero if all listeners are available; otherwise a
199 * negative errno value is returned.
195 */ 200 */
196static int make_socks(struct svc_serv *serv, int proto) 201static int make_socks(struct svc_serv *serv)
197{ 202{
198 static int warned; 203 static int warned;
199 struct svc_xprt *xprt; 204 struct svc_xprt *xprt;
200 int err = 0; 205 int err = 0;
201 206
202 if (proto == IPPROTO_UDP || nlm_udpport) { 207 xprt = svc_find_xprt(serv, "udp", 0, 0);
203 xprt = svc_find_xprt(serv, "udp", 0, 0); 208 if (!xprt)
204 if (!xprt) 209 err = svc_create_xprt(serv, "udp", nlm_udpport,
205 err = svc_create_xprt(serv, "udp", nlm_udpport, 210 SVC_SOCK_DEFAULTS);
206 SVC_SOCK_DEFAULTS); 211 else
207 else 212 svc_xprt_put(xprt);
208 svc_xprt_put(xprt); 213 if (err >= 0) {
209 }
210 if (err >= 0 && (proto == IPPROTO_TCP || nlm_tcpport)) {
211 xprt = svc_find_xprt(serv, "tcp", 0, 0); 214 xprt = svc_find_xprt(serv, "tcp", 0, 0);
212 if (!xprt) 215 if (!xprt)
213 err = svc_create_xprt(serv, "tcp", nlm_tcpport, 216 err = svc_create_xprt(serv, "tcp", nlm_tcpport,
@@ -237,11 +240,8 @@ lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */
237 /* 240 /*
238 * Check whether we're already up and running. 241 * Check whether we're already up and running.
239 */ 242 */
240 if (nlmsvc_rqst) { 243 if (nlmsvc_rqst)
241 if (proto)
242 error = make_socks(nlmsvc_rqst->rq_server, proto);
243 goto out; 244 goto out;
244 }
245 245
246 /* 246 /*
247 * Sanity check: if there's no pid, 247 * Sanity check: if there's no pid,
@@ -258,7 +258,8 @@ lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */
258 goto out; 258 goto out;
259 } 259 }
260 260
261 if ((error = make_socks(serv, proto)) < 0) 261 error = make_socks(serv);
262 if (error < 0)
262 goto destroy_and_out; 263 goto destroy_and_out;
263 264
264 /* 265 /*