svn commit: r206798 - stable/7/sys/kern

Peter Holm pho at FreeBSD.org
Sun Apr 18 12:50:27 UTC 2010


Author: pho
Date: Sun Apr 18 12:50:26 2010
New Revision: 206798
URL: http://svn.freebsd.org/changeset/base/206798

Log:
  Fix incorrect assertion. If the caller passed in no lock flags
  (i.e. just checking the vnode for validity) then there is a window
  between the VI_UNLOCK() in _vn_lock(9) and the subsequent VI_LOCK()
  in vget() where another thread could have set VI_DOOMED.
  
  Submitted by:	Matthew Fleming <matthew fleming isilon com>
  Reviewed by:	kib

Modified:
  stable/7/sys/kern/vfs_subr.c

Modified: stable/7/sys/kern/vfs_subr.c
==============================================================================
--- stable/7/sys/kern/vfs_subr.c	Sun Apr 18 12:43:33 2010	(r206797)
+++ stable/7/sys/kern/vfs_subr.c	Sun Apr 18 12:50:26 2010	(r206798)
@@ -2064,10 +2064,18 @@ vget(struct vnode *vp, int flags, struct
 		return (error);
 	}
 	VI_LOCK(vp);
+	/*
+	 * Deal with a timing window when the interlock is not held
+	 * and VI_DOOMED can be set, since we only have a holdcnt,
+	 * not a usecount.
+	 */
+	if (vp->v_iflag & VI_DOOMED && (flags & LK_RETRY) == 0) {
+	       KASSERT((flags & LK_TYPE_MASK) == 0, ("Unexpected flags %x", flags));
+	       vdropl(vp);
+	       return (ENOENT);
+	}
 	/* Upgrade our holdcnt to a usecount. */
 	v_upgrade_usecount(vp);
-	if (vp->v_iflag & VI_DOOMED && (flags & LK_RETRY) == 0)
-		panic("vget: vn_lock failed to return ENOENT\n");
 	if (oweinact) {
 		if (vp->v_iflag & VI_OWEINACT)
 			vinactive(vp, td);


More information about the svn-src-all mailing list