[PATCH] knfsd: Correctly handle error condition from lockd_up

If lockd_up fails - what should we expect?  Do we have to later call
lockd_down?

Well the nfs client thinks "no", the nfs server thinks "yes".  lockd thinks
"yes".

The only answer that really makes sense is "no" !!

So:
  Make lockd_up only increment  nlmsvc_users on success.
  Make nfsd handle errors from lockd_up properly.
  Make sure lockd_up(0) never fails when lockd is running
    so that the 'reclaimer' call to lockd_up doesn't need to
    be error checked.

Cc: "J. Bruce Fields" <bfields@fieldses.org>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
NeilBrown 2006-10-02 02:17:53 -07:00 committed by Linus Torvalds
parent 7dcf91ec66
commit 4a3ae42dc3
3 changed files with 16 additions and 14 deletions

View File

@ -202,7 +202,7 @@ reclaimer(void *ptr)
/* This one ensures that our parent doesn't terminate while the /* This one ensures that our parent doesn't terminate while the
* reclaim is in progress */ * reclaim is in progress */
lock_kernel(); lock_kernel();
lockd_up(0); lockd_up(0); /* note: this cannot fail as lockd is already running */
nlmclnt_prepare_reclaim(host); nlmclnt_prepare_reclaim(host);
/* First, reclaim all locks that have been marked. */ /* First, reclaim all locks that have been marked. */

View File

@ -253,16 +253,12 @@ lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */
int error = 0; int error = 0;
mutex_lock(&nlmsvc_mutex); mutex_lock(&nlmsvc_mutex);
/*
* Unconditionally increment the user count ... this is
* the number of clients who _want_ a lockd process.
*/
nlmsvc_users++;
/* /*
* Check whether we're already up and running. * Check whether we're already up and running.
*/ */
if (nlmsvc_pid) { if (nlmsvc_pid) {
error = make_socks(nlmsvc_serv, proto); if (proto)
error = make_socks(nlmsvc_serv, proto);
goto out; goto out;
} }
@ -270,7 +266,7 @@ lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */
* Sanity check: if there's no pid, * Sanity check: if there's no pid,
* we should be the first user ... * we should be the first user ...
*/ */
if (nlmsvc_users > 1) if (nlmsvc_users)
printk(KERN_WARNING printk(KERN_WARNING
"lockd_up: no pid, %d users??\n", nlmsvc_users); "lockd_up: no pid, %d users??\n", nlmsvc_users);
@ -302,6 +298,8 @@ lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */
destroy_and_out: destroy_and_out:
svc_destroy(serv); svc_destroy(serv);
out: out:
if (!error)
nlmsvc_users++;
mutex_unlock(&nlmsvc_mutex); mutex_unlock(&nlmsvc_mutex);
return error; return error;
} }

View File

@ -221,18 +221,22 @@ static int nfsd_init_socks(int port)
if (!list_empty(&nfsd_serv->sv_permsocks)) if (!list_empty(&nfsd_serv->sv_permsocks))
return 0; return 0;
error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
if (error < 0)
return error;
error = lockd_up(IPPROTO_UDP); error = lockd_up(IPPROTO_UDP);
if (error >= 0) {
error = svc_makesock(nfsd_serv, IPPROTO_UDP, port);
if (error < 0)
lockd_down();
}
if (error < 0) if (error < 0)
return error; return error;
#ifdef CONFIG_NFSD_TCP #ifdef CONFIG_NFSD_TCP
error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
if (error < 0)
return error;
error = lockd_up(IPPROTO_TCP); error = lockd_up(IPPROTO_TCP);
if (error >= 0) {
error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
if (error < 0)
lockd_down();
}
if (error < 0) if (error < 0)
return error; return error;
#endif #endif