--- a/sys/vfs/nfs/nfs_vnops.c +++ b/sys/vfs/nfs/nfs_vnops.c @@ -1269,7 +1269,15 @@ nfsmout: if (error) { if (newvp != NULLVP) { - vrele(newvp); + /* + * nfs_nget() returned newvp LK_EXCLUSIVE-locked; + * only the dvp-echo case (vref'd, lock owned by the + * caller) must be released without unlocking. + */ + if (newvp == dvp) + vrele(newvp); + else + vput(newvp); *vpp = NULLVP; } if ((cnp->cn_nameiop == NAMEI_CREATE || @@ -2345,7 +2353,8 @@ */ if (error == EEXIST || (!error && !gotvp)) { if (newvp) { - vrele(newvp); + /* nfsm_mtofh()-sourced: still LK_EXCLUSIVE-locked */ + vput(newvp); newvp = NULL; } error = nfs_lookitup(dvp, cnp->cn_nameptr, len, cnp->cn_cred, @@ -2357,8 +2366,17 @@ } } if (error) { - if (newvp) - vrele(newvp); + if (newvp) { + /* + * newvp came from nfs_nget()/nfs_lookitup() and is + * LK_EXCLUSIVE-locked; only the lookitup dvp-echo + * case must be released without unlocking. + */ + if (newvp == dvp) + vrele(newvp); + else + vput(newvp); + } } else { nfs_knote(dvp, NOTE_WRITE | NOTE_LINK); *ap->a_vpp = newvp;