In nfs_nget(), we must initialize the fh in the nfsnode before inserting the

vnode into the vfs hash. Otherwise, another thread walking the hash can trip
on an nfsnode with an uninitialized or partially initialized fh.
Thanks to ups@ for spotting this race.
This commit is contained in:
Mohan Srinivasan 2006-11-29 02:21:40 +00:00
parent a6b2640236
commit 594ece53bc
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=164735

View File

@ -160,6 +160,12 @@ nfs_nget(struct mount *mntp, nfsfh_t *fhp, int fhsize, struct nfsnode **npp, int
*/
vp->v_vnlock->lk_flags |= LK_CANRECURSE;
vp->v_vnlock->lk_flags &= ~LK_NOSHARE;
if (fhsize > NFS_SMALLFH) {
MALLOC(np->n_fhp, nfsfh_t *, fhsize, M_NFSBIGFH, M_WAITOK);
} else
np->n_fhp = &np->n_fh;
bcopy((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize);
np->n_fhsize = fhsize;
error = vfs_hash_insert(vp, hash, flags,
td, &nvp, nfs_vncmpf, &ncmp);
if (error)
@ -169,12 +175,6 @@ nfs_nget(struct mount *mntp, nfsfh_t *fhp, int fhsize, struct nfsnode **npp, int
/* vfs_hash_insert() vput()'s the losing vnode */
return (0);
}
if (fhsize > NFS_SMALLFH) {
MALLOC(np->n_fhp, nfsfh_t *, fhsize, M_NFSBIGFH, M_WAITOK);
} else
np->n_fhp = &np->n_fh;
bcopy((caddr_t)fhp, (caddr_t)np->n_fhp, fhsize);
np->n_fhsize = fhsize;
*npp = np;
return (0);