diff options
author | mohans <mohans@FreeBSD.org> | 2006-11-27 19:06:43 +0000 |
---|---|---|
committer | mohans <mohans@FreeBSD.org> | 2006-11-27 19:06:43 +0000 |
commit | 9ca7ca48b8895f4f6a43035a5206bc7601998e97 (patch) | |
tree | 317c5fcf088762934fb4b28f4c4439bf1afb9268 /sys/nfsclient/nfs_node.c | |
parent | b92c02c4c737fdf42c084a51fde89a9bafc1cf7e (diff) | |
download | FreeBSD-src-9ca7ca48b8895f4f6a43035a5206bc7601998e97.zip FreeBSD-src-9ca7ca48b8895f4f6a43035a5206bc7601998e97.tar.gz |
Fix for a bug caused by a race when 2 threads lookup the same
file. Leave the loser's lock(s) initialized, so the reclaim logic can
unconditionally destroy them when that race occurs (or if the vfs hash
insert happened to fail for some other reason). Thanks to ups@ for a
careful review of the code.
Reported by : Kris Kennaway
Diffstat (limited to 'sys/nfsclient/nfs_node.c')
-rw-r--r-- | sys/nfsclient/nfs_node.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c index 242ef5e..85580a8 100644 --- a/sys/nfsclient/nfs_node.c +++ b/sys/nfsclient/nfs_node.c @@ -148,6 +148,13 @@ nfs_nget(struct mount *mntp, nfsfh_t *fhp, int fhsize, struct nfsnode **npp, int vp->v_bufobj.bo_ops = &buf_ops_nfs; vp->v_data = np; np->n_vnode = vp; + /* + * Initialize the mutex even if the vnode is going to be a loser. + * This simplifies the logic in reclaim, which can then unconditionally + * destroy the mutex (in the case of the loser, or if hash_insert happened + * to return an error no special casing is needed). + */ + mtx_init(&np->n_mtx, "NFSnode lock", NULL, MTX_DEF); /* * NFS supports recursive and shared locking. */ @@ -168,7 +175,6 @@ nfs_nget(struct mount *mntp, nfsfh_t *fhp, int fhsize, struct nfsnode **npp, int np->n_fhp = &np->n_fh; bcopy((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize); np->n_fhsize = fhsize; - mtx_init(&np->n_mtx, "NFSnode lock", NULL, MTX_DEF); *npp = np; return (0); |