diff options
author | Rick Macklem <rmacklem@FreeBSD.org> | 2012-05-12 22:20:55 +0000 |
---|---|---|
committer | Rick Macklem <rmacklem@FreeBSD.org> | 2012-05-12 22:20:55 +0000 |
commit | 2108487ead4bb29c93a56a7518e478cb73c43a33 (patch) | |
tree | 0d9ff839421e994d9fba1a12cefbe8826ddbef35 /sys/fs | |
parent | f2f9999d8b198d4aeef3bada3ccee3b1e4a2a38a (diff) | |
download | src-2108487ead4bb29c93a56a7518e478cb73c43a33.tar.gz src-2108487ead4bb29c93a56a7518e478cb73c43a33.zip |
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
Notes
Notes:
svn path=/head/; revision=235381
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/nfsserver/nfs_nfsdstate.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index f44917e34a98..e9962c720cc9 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); |