Index: head/sys/kern/vfs_subr.c =================================================================== --- head/sys/kern/vfs_subr.c +++ head/sys/kern/vfs_subr.c @@ -2861,6 +2861,8 @@ * Remove a vnode from the free list, mark it as in use, * and put it on the active list. */ + VNASSERT(vp->v_mount != NULL, vp, + ("_vhold: vnode not on per mount vnode list")); mp = vp->v_mount; mtx_lock(&mp->mnt_listmtx); if ((vp->v_mflag & VMP_TMPMNTFREELIST) != 0) { @@ -2935,21 +2937,35 @@ if ((vp->v_iflag & VI_OWEINACT) == 0) { vp->v_iflag &= ~VI_ACTIVE; mp = vp->v_mount; - mtx_lock(&mp->mnt_listmtx); - if (active) { - TAILQ_REMOVE(&mp->mnt_activevnodelist, vp, + if (mp != NULL) { + mtx_lock(&mp->mnt_listmtx); + if (active) { + TAILQ_REMOVE(&mp->mnt_activevnodelist, + vp, v_actfreelist); + mp->mnt_activevnodelistsize--; + } + TAILQ_INSERT_TAIL(&mp->mnt_tmpfreevnodelist, + vp, v_actfreelist); + mp->mnt_tmpfreevnodelistsize++; + vp->v_iflag |= VI_FREE; + vp->v_mflag |= VMP_TMPMNTFREELIST; + VI_UNLOCK(vp); + if (mp->mnt_tmpfreevnodelistsize >= + mnt_free_list_batch) + vnlru_return_batch_locked(mp); + mtx_unlock(&mp->mnt_listmtx); + } else { + VNASSERT(active == 0, vp, + ("vdropl: active vnode not on per mount " + "vnode list")); + mtx_lock(&vnode_free_list_mtx); + TAILQ_INSERT_TAIL(&vnode_free_list, vp, v_actfreelist); - mp->mnt_activevnodelistsize--; + freevnodes++; + vp->v_iflag |= VI_FREE; + VI_UNLOCK(vp); + mtx_unlock(&vnode_free_list_mtx); } - TAILQ_INSERT_TAIL(&mp->mnt_tmpfreevnodelist, vp, - v_actfreelist); - mp->mnt_tmpfreevnodelistsize++; - vp->v_iflag |= VI_FREE; - vp->v_mflag |= VMP_TMPMNTFREELIST; - VI_UNLOCK(vp); - if (mp->mnt_tmpfreevnodelistsize >= mnt_free_list_batch) - vnlru_return_batch_locked(mp); - mtx_unlock(&mp->mnt_listmtx); } else { VI_UNLOCK(vp); counter_u64_add(free_owe_inact, 1);