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

Reply via email to