svn commit: r188610 - in stable/7/sys: . contrib/pf dev/ath/ath_hal dev/cxgb kern sys

Konstantin Belousov kib at FreeBSD.org
Sat Feb 14 12:42:55 PST 2009


Author: kib
Date: Sat Feb 14 20:42:54 2009
New Revision: 188610
URL: http://svn.freebsd.org/changeset/base/188610

Log:
  MFC r182364:
  Introduce the VV_FORCEINSMQ vnode flag. It instructs the insmnque() function
  to ignore the unmounting and forces insertion of the vnode into the mount
  vnode list.
  
  Change insmntque() to fail when forced unmount is in progress and
  VV_FORCEINSMQ is not specified.
  
  Add an assertion to the insmntque(), requiring the vnode to be
  exclusively locked for mp-safe filesystems.
  MFC note: because zfs in stable/7 does not follow the insmntque() protocol,
  the assertion is commented out.
  
  Use the VV_FORCEINSMQ for the creation of the syncvnode.

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)
  stable/7/sys/dev/ath/ath_hal/   (props changed)
  stable/7/sys/dev/cxgb/   (props changed)
  stable/7/sys/kern/vfs_subr.c
  stable/7/sys/sys/vnode.h

Modified: stable/7/sys/kern/vfs_subr.c
==============================================================================
--- stable/7/sys/kern/vfs_subr.c	Sat Feb 14 19:46:28 2009	(r188609)
+++ stable/7/sys/kern/vfs_subr.c	Sat Feb 14 20:42:54 2009	(r188610)
@@ -1007,17 +1007,30 @@ int
 insmntque1(struct vnode *vp, struct mount *mp,
 	void (*dtr)(struct vnode *, void *), void *dtr_arg)
 {
+	int locked;
 
 	KASSERT(vp->v_mount == NULL,
 		("insmntque: vnode already on per mount vnode list"));
 	VNASSERT(mp != NULL, vp, ("Don't call insmntque(foo, NULL)"));
+#if 0
+#ifdef DEBUG_VFS_LOCKS
+	if (!VFS_NEEDSGIANT(mp))
+		ASSERT_VOP_ELOCKED(vp,
+		    "insmntque: mp-safe fs and non-locked vp");
+#endif
+#endif
 	MNT_ILOCK(mp);
 	if ((mp->mnt_kern_flag & MNTK_NOINSMNTQ) != 0 &&
-	    mp->mnt_nvnodelistsize == 0) {
-		MNT_IUNLOCK(mp);
-		if (dtr != NULL)
-			dtr(vp, dtr_arg);
-		return (EBUSY);
+	    ((mp->mnt_kern_flag & MNTK_UNMOUNTF) != 0 ||
+	     mp->mnt_nvnodelistsize == 0)) {
+		locked = VOP_ISLOCKED(vp, curthread);
+		if (!locked || (locked == LK_EXCLUSIVE &&
+		     (vp->v_vflag & VV_FORCEINSMQ) == 0)) {
+			MNT_IUNLOCK(mp);
+			if (dtr != NULL)
+				dtr(vp, dtr_arg);
+			return (EBUSY);
+		}
 	}
 	vp->v_mount = mp;
 	MNT_REF(mp);
@@ -3140,9 +3153,13 @@ vfs_allocate_syncvnode(struct mount *mp)
 		return (error);
 	}
 	vp->v_type = VNON;
+	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
+	vp->v_vflag |= VV_FORCEINSMQ;
 	error = insmntque(vp, mp);
 	if (error != 0)
 		panic("vfs_allocate_syncvnode: insmntque failed");
+	vp->v_vflag &= ~VV_FORCEINSMQ;
+	VOP_UNLOCK(vp, 0, curthread);
 	/*
 	 * Place the vnode onto the syncer worklist. We attempt to
 	 * scatter them about on the list so that they will go off

Modified: stable/7/sys/sys/vnode.h
==============================================================================
--- stable/7/sys/sys/vnode.h	Sat Feb 14 19:46:28 2009	(r188609)
+++ stable/7/sys/sys/vnode.h	Sat Feb 14 20:42:54 2009	(r188610)
@@ -251,6 +251,7 @@ struct xvnode {
 #define	VV_NOKNOTE	0x0200	/* don't activate knotes on this vnode */
 #define	VV_DELETED	0x0400	/* should be removed */
 #define	VV_MD		0x0800	/* vnode backs the md device */
+#define	VV_FORCEINSMQ	0x1000	/* force the insmntque to succeed */
 
 /*
  * Vnode attributes.  A field value of VNOVAL represents a field whose value


More information about the svn-src-all mailing list