* Drop the hold count of the vnode. If this is the last reference to * the vnode we place it on the free list unless it has been vgone'd * (marked VIRF_DOOMED) in which case we will free it. * * Because the vnode vm object keeps a hold reference on the vnode if * there is at least one resident non-cached page, the vnode cannot * leave the active list without the page cleanup done. */
| 3515 | * leave the active list without the page cleanup done. |
| 3516 | */ |
| 3517 | static void |
| 3518 | vdrop_deactivate(struct vnode *vp) |
| 3519 | { |
| 3520 | struct mount *mp; |
| 3521 | |
| 3522 | ASSERT_VI_LOCKED(vp, __func__); |
| 3523 | /* |
| 3524 | * Mark a vnode as free: remove it from its active list |
| 3525 | * and put it up for recycling on the freelist. |
| 3526 | */ |
| 3527 | VNASSERT(!VN_IS_DOOMED(vp), vp, |
| 3528 | ("vdrop: returning doomed vnode")); |
| 3529 | VNASSERT((vp->v_iflag & VI_OWEINACT) == 0, vp, |
| 3530 | ("vnode with VI_OWEINACT set")); |
| 3531 | VNASSERT((vp->v_iflag & VI_DEFINACT) == 0, vp, |
| 3532 | ("vnode with VI_DEFINACT set")); |
| 3533 | if (vp->v_mflag & VMP_LAZYLIST) { |
| 3534 | mp = vp->v_mount; |
| 3535 | mtx_lock(&mp->mnt_listmtx); |
| 3536 | VNASSERT(vp->v_mflag & VMP_LAZYLIST, vp, ("lost VMP_LAZYLIST")); |
| 3537 | /* |
| 3538 | * Don't remove the vnode from the lazy list if another thread |
| 3539 | * has increased the hold count. It may have re-enqueued the |
| 3540 | * vnode to the lazy list and is now responsible for its |
| 3541 | * removal. |
| 3542 | */ |
| 3543 | if (vp->v_holdcnt == 0) { |
| 3544 | vp->v_mflag &= ~VMP_LAZYLIST; |
| 3545 | TAILQ_REMOVE(&mp->mnt_lazyvnodelist, vp, v_lazylist); |
| 3546 | mp->mnt_lazyvnodelistsize--; |
| 3547 | } |
| 3548 | mtx_unlock(&mp->mnt_listmtx); |
| 3549 | } |
| 3550 | vdbatch_enqueue(vp); |
| 3551 | } |
| 3552 | |
| 3553 | static void __noinline |
| 3554 | vdropl_final(struct vnode *vp) |
no test coverage detected