Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 May 2013 11:31:56 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r250852 - head/sys/fs/nullfs
Message-ID:  <201305211131.r4LBVu9x056490@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Tue May 21 11:31:56 2013
New Revision: 250852
URL: http://svnweb.freebsd.org/changeset/base/250852

Log:
  Do not leak the NULLV_NOUNLOCK flag from the nullfs_unlink_lowervp(),
  for the case when the nullfs vnode is not reclaimed.  Otherwise, later
  reclamation would not unlock the lower vnode.
  
  Reported by:	antoine
  Tested by:	pho
  Sponsored by:	The FreeBSD Foundation
  MFC after:	1 week

Modified:
  head/sys/fs/nullfs/null_vfsops.c

Modified: head/sys/fs/nullfs/null_vfsops.c
==============================================================================
--- head/sys/fs/nullfs/null_vfsops.c	Tue May 21 11:24:32 2013	(r250851)
+++ head/sys/fs/nullfs/null_vfsops.c	Tue May 21 11:31:56 2013	(r250852)
@@ -409,16 +409,28 @@ nullfs_unlink_lowervp(struct mount *mp, 
 	vhold(vp);
 	vunref(vp);
 
-	/*
-	 * If vunref() dropped the last use reference on the nullfs
-	 * vnode, it must be reclaimed, and its lock was split from
-	 * the lower vnode lock.  Need to do extra unlock before
-	 * allowing the final vdrop() to free the vnode.
-	 */
 	if (vp->v_usecount == 0) {
+		/*
+		 * If vunref() dropped the last use reference on the
+		 * nullfs vnode, it must be reclaimed, and its lock
+		 * was split from the lower vnode lock.  Need to do
+		 * extra unlock before allowing the final vdrop() to
+		 * free the vnode.
+		 */
 		KASSERT((vp->v_iflag & VI_DOOMED) != 0,
-		    ("not reclaimed %p", vp));
+		    ("not reclaimed nullfs vnode %p", vp));
 		VOP_UNLOCK(vp, 0);
+	} else {
+		/*
+		 * Otherwise, the nullfs vnode still shares the lock
+		 * with the lower vnode, and must not be unlocked.
+		 * Also clear the NULLV_NOUNLOCK, the flag is not
+		 * relevant for future reclamations.
+		 */
+		ASSERT_VOP_ELOCKED(vp, "unlink_lowervp");
+		KASSERT((vp->v_iflag & VI_DOOMED) == 0,
+		    ("reclaimed nullfs vnode %p", vp));
+		xp->null_flags &= ~NULLV_NOUNLOCK;
 	}
 	vdrop(vp);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201305211131.r4LBVu9x056490>