On 10 Sep, Don Lewis wrote: > It looks like the call to vrele() from vn_close() is executing the > following code: > > if (vp->v_usecount == 1) { > vp->v_usecount--; > /* > * We must call VOP_INACTIVE with the node locked. > * If we are doing a vput, the node is already locked, > * but, in the case of vrele, we must explicitly lock > * the vnode before calling VOP_INACTIVE. > */ > if (vn_lock(vp, LK_EXCLUSIVE | LK_INTERLOCK, td) == 0) > VOP_INACTIVE(vp, td); > VI_LOCK(vp); > if (VSHOULDFREE(vp)) > vfree(vp); > else > vlruvp(vp); > VI_UNLOCK(vp); > > It has decremented v_usecount to 0, grabbed an exclusive lock on the > vnode, and has called VOP_INACTIVE().
> It looks like nfs_inactive() is executing the following code: > > if (sp) { > /* > * We need a reference to keep the vnode from being > * recycled by getnewvnode while we do the I/O > * associated with discarding the buffers unless we > * are being forcibly unmounted in which case we already > * have our own reference. > */ > if (ap->a_vp->v_usecount > 0) > (void) nfs_vinvalbuf(ap->a_vp, 0, sp->s_cred, td, 1); > else if (vget(ap->a_vp, 0, td)) > panic("nfs_inactive: lost vnode"); > else { > (void) nfs_vinvalbuf(ap->a_vp, 0, sp->s_cred, td, 1); > vrele(ap->a_vp); > } > A potentially better solution just occurred to me. It looks like it would be better if vrele() waited to decrement v_usecount until *after* the call to VOP_INACTIVE() (and after the call to VI_LOCK()). If that were done, nfs_inactive() wouldn't need to muck with v_usecount at all. To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-current" in the body of the message