From 1b7df30abd5674475a59bf1c84b42774101bc3a6 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Thu, 11 Feb 2010 12:40:45 -0800 Subject: [PATCH] kernel - Fix "cleaned vnode isn't" panic * Fix the "cleaned vnode isn't" panic. This panic was occuring due to vrecycle() not checking for a vgone*() recursion. Adjust vrecycle() to check for the recursion. The recursion can be detected by testing the VRECLAIMED flag. * Under certain circumstances hammer_vop_inactive() was calling vrecycle(). This could cause the underlying vnode to be modified after it has been destroyed as the recursion returns. * Add a KKASSERT() in vgone_vxlocked() to detect the condition earlier if it occurs again. --- sys/kern/vfs_subr.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index 1b117bda96..b70331d060 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -1254,11 +1254,14 @@ vrevoke(struct vnode *vp, struct ucred *cred) * * Directory vnodes in the namecache with children cannot be immediately * recycled because numerous VOP_N*() ops require them to be stable. + * + * To avoid recursive recycling from VOP_INACTIVE implemenetations this + * function is a NOP if VRECLAIMED is already set. */ int vrecycle(struct vnode *vp) { - if (vp->v_sysref.refcnt <= 1) { + if (vp->v_sysref.refcnt <= 1 && (vp->v_flag & VRECLAIMED) == 0) { if (cache_inval_vp_nonblock(vp)) return(0); vgone_vxlocked(vp); @@ -1320,8 +1323,10 @@ vgone_vxlocked(struct vnode *vp) /* * Delete from old mount point vnode list, if on one. */ - if (vp->v_mount != NULL) + if (vp->v_mount != NULL) { + KKASSERT(vp->v_data == NULL); insmntque(vp, NULL); + } /* * If special device, remove it from special device alias list -- 2.11.4.GIT