summaryrefslogtreecommitdiffstats
path: root/sys/fs/nfsserver
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2012-05-12 22:20:55 +0000
committerrmacklem <rmacklem@FreeBSD.org>2012-05-12 22:20:55 +0000
commit4ff8331c1b8e7243d13d6e3c842371f4c40b1f64 (patch)
tree0d9ff839421e994d9fba1a12cefbe8826ddbef35 /sys/fs/nfsserver
parent2325662608ef525d2b16f218c7f92205ae571d5c (diff)
downloadFreeBSD-src-4ff8331c1b8e7243d13d6e3c842371f4c40b1f64.zip
FreeBSD-src-4ff8331c1b8e7243d13d6e3c842371f4c40b1f64.tar.gz
Fix two cases in the new NFS server where a tsleep() is
used, when the code should actually protect the tested variable with a mutex. Since the tsleep()s had a 10sec timeout, the race would have only delayed the allocation of a new clientid for a client. The sleeps will also rarely occur, since having a callback in progress when a client acquires a new clientid, is unlikely. in practice, since having a callback in progress when a fresh clientid is being acquired by a client is unlikely. MFC after: 1 month
Diffstat (limited to 'sys/fs/nfsserver')
-rw-r--r--sys/fs/nfsserver/nfs_nfsdstate.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c
index f44917e..e9962c7 100644
--- a/sys/fs/nfsserver/nfs_nfsdstate.c
+++ b/sys/fs/nfsserver/nfs_nfsdstate.c
@@ -331,11 +331,13 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
* Must wait until any outstanding callback on the old clp
* completes.
*/
+ NFSLOCKSTATE();
while (clp->lc_cbref) {
clp->lc_flags |= LCL_WAKEUPWANTED;
- (void) tsleep((caddr_t)clp, PZERO - 1,
+ (void)mtx_sleep(clp, NFSSTATEMUTEXPTR, PZERO - 1,
"nfsd clp", 10 * hz);
}
+ NFSUNLOCKSTATE();
nfsrv_zapclient(clp, p);
*new_clpp = NULL;
goto out;
@@ -385,10 +387,13 @@ nfsrv_setclient(struct nfsrv_descript *nd, struct nfsclient **new_clpp,
* Must wait until any outstanding callback on the old clp
* completes.
*/
+ NFSLOCKSTATE();
while (clp->lc_cbref) {
clp->lc_flags |= LCL_WAKEUPWANTED;
- (void) tsleep((caddr_t)clp, PZERO - 1, "nfsd clp", 10 * hz);
+ (void)mtx_sleep(clp, NFSSTATEMUTEXPTR, PZERO - 1, "nfsd clp",
+ 10 * hz);
}
+ NFSUNLOCKSTATE();
nfsrv_zapclient(clp, p);
*new_clpp = NULL;
@@ -3816,11 +3821,9 @@ nfsrv_docallback(struct nfsclient *clp, int procnum,
clp->lc_cbref--;
if ((clp->lc_flags & LCL_WAKEUPWANTED) && clp->lc_cbref == 0) {
clp->lc_flags &= ~LCL_WAKEUPWANTED;
- NFSUNLOCKSTATE();
- wakeup((caddr_t)clp);
- } else {
- NFSUNLOCKSTATE();
+ wakeup(clp);
}
+ NFSUNLOCKSTATE();
NFSEXITCODE(error);
return (error);
OpenPOWER on IntegriCloud