Module Name:    src
Committed By:   hannken
Date:           Sun Jun  4 07:58:30 UTC 2017

Modified Files:
        src/sys/kern: vfs_subr.c vfs_vnode.c
        src/sys/sys: vnode_impl.h

Log Message:
A vnode is usually called "active", if it has an associated file system
node and a usecount greater zero.  Therefore rename state "VS_ACTIVE"
to "VS_LOADED" and add a new synthetic state "VS_ACTIVE" for VSTATE_ASSERT()
to assert an active vnode.

Add VSTATE_ASSERT_UNLOCKED() to be used with v_interlock unheld and
move the state assertion macros to sys/vnode_impl.h.


To generate a diff of this commit:
cvs rdiff -u -r1.467 -r1.468 src/sys/kern/vfs_subr.c
cvs rdiff -u -r1.93 -r1.94 src/sys/kern/vfs_vnode.c
cvs rdiff -u -r1.13 -r1.14 src/sys/sys/vnode_impl.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/vfs_subr.c
diff -u src/sys/kern/vfs_subr.c:1.467 src/sys/kern/vfs_subr.c:1.468
--- src/sys/kern/vfs_subr.c:1.467	Fri May 26 14:34:19 2017
+++ src/sys/kern/vfs_subr.c	Sun Jun  4 07:58:29 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_subr.c,v 1.467 2017/05/26 14:34:19 riastradh Exp $	*/
+/*	$NetBSD: vfs_subr.c,v 1.468 2017/06/04 07:58:29 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.467 2017/05/26 14:34:19 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.468 2017/06/04 07:58:29 hannken Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -1055,12 +1055,14 @@ vstate_name(enum vnode_state state)
 {
 
 	switch (state) {
+	case VS_ACTIVE:
+		return "ACTIVE";
 	case VS_MARKER:
 		return "MARKER";
 	case VS_LOADING:
 		return "LOADING";
-	case VS_ACTIVE:
-		return "ACTIVE";
+	case VS_LOADED:
+		return "LOADED";
 	case VS_BLOCKED:
 		return "BLOCKED";
 	case VS_RECLAIMING:

Index: src/sys/kern/vfs_vnode.c
diff -u src/sys/kern/vfs_vnode.c:1.93 src/sys/kern/vfs_vnode.c:1.94
--- src/sys/kern/vfs_vnode.c:1.93	Sun May 28 16:39:41 2017
+++ src/sys/kern/vfs_vnode.c	Sun Jun  4 07:58:29 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_vnode.c,v 1.93 2017/05/28 16:39:41 hannken Exp $	*/
+/*	$NetBSD: vfs_vnode.c,v 1.94 2017/06/04 07:58:29 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -100,7 +100,7 @@
  *			will never change its state.
  *	- LOADING	Vnode is associating underlying file system and not
  *			yet ready to use.
- *	- ACTIVE	Vnode has associated underlying file system and is
+ *	- LOADED	Vnode has associated underlying file system and is
  *			ready to use.
  *	- BLOCKED	Vnode is active but cannot get new references.
  *	- RECLAIMING	Vnode is disassociating from the underlying file
@@ -109,19 +109,19 @@
  *			and is dead.
  *
  *	Valid state changes are:
- *	LOADING -> ACTIVE
+ *	LOADING -> LOADED
  *			Vnode has been initialised in vcache_get() or
  *			vcache_new() and is ready to use.
- *	ACTIVE -> RECLAIMING
+ *	LOADED -> RECLAIMING
  *			Vnode starts disassociation from underlying file
  *			system in vcache_reclaim().
  *	RECLAIMING -> RECLAIMED
  *			Vnode finished disassociation from underlying file
  *			system in vcache_reclaim().
- *	ACTIVE -> BLOCKED
+ *	LOADED -> BLOCKED
  *			Either vcache_rekey*() is changing the vnode key or
  *			vrelel() is about to call VOP_INACTIVE().
- *	BLOCKED -> ACTIVE
+ *	BLOCKED -> LOADED
  *			The block condition is over.
  *	LOADING -> RECLAIMED
  *			Either vcache_get() or vcache_new() failed to
@@ -156,7 +156,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.93 2017/05/28 16:39:41 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.94 2017/06/04 07:58:29 hannken Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -231,26 +231,30 @@ extern struct vfsops	dead_vfsops;
 
 #if defined(DIAGNOSTIC)
 
+#define VSTATE_VALID(state) \
+	((state) != VS_ACTIVE && (state) != VS_MARKER)
 #define VSTATE_GET(vp) \
 	vstate_assert_get((vp), __func__, __LINE__)
 #define VSTATE_CHANGE(vp, from, to) \
 	vstate_assert_change((vp), (from), (to), __func__, __LINE__)
 #define VSTATE_WAIT_STABLE(vp) \
 	vstate_assert_wait_stable((vp), __func__, __LINE__)
-#define VSTATE_ASSERT(vp, state) \
-	vstate_assert((vp), (state), __func__, __LINE__)
 
-static void
-vstate_assert(vnode_t *vp, enum vnode_state state, const char *func, int line)
+void
+_vstate_assert(vnode_t *vp, enum vnode_state state, const char *func, int line)
 {
 	vnode_impl_t *vip = VNODE_TO_VIMPL(vp);
 
 	KASSERTMSG(mutex_owned(vp->v_interlock), "at %s:%d", func, line);
 
-	if (__predict_true(vip->vi_state == state))
+	if (state == VS_ACTIVE && vp->v_usecount > 0 &&
+	    (vip->vi_state == VS_LOADED || vip->vi_state == VS_BLOCKED))
 		return;
-	vnpanic(vp, "state is %s, expected %s at %s:%d",
-	    vstate_name(vip->vi_state), vstate_name(state), func, line);
+	if (vip->vi_state == state)
+		return;
+	vnpanic(vp, "state is %s, usecount %d, expected %s at %s:%d",
+	    vstate_name(vip->vi_state), vp->v_usecount,
+	    vstate_name(state), func, line);
 }
 
 static enum vnode_state
@@ -259,7 +263,7 @@ vstate_assert_get(vnode_t *vp, const cha
 	vnode_impl_t *vip = VNODE_TO_VIMPL(vp);
 
 	KASSERTMSG(mutex_owned(vp->v_interlock), "at %s:%d", func, line);
-	if (vip->vi_state == VS_MARKER)
+	if (! VSTATE_VALID(vip->vi_state))
 		vnpanic(vp, "state is %s at %s:%d",
 		    vstate_name(vip->vi_state), func, line);
 
@@ -272,14 +276,14 @@ vstate_assert_wait_stable(vnode_t *vp, c
 	vnode_impl_t *vip = VNODE_TO_VIMPL(vp);
 
 	KASSERTMSG(mutex_owned(vp->v_interlock), "at %s:%d", func, line);
-	if (vip->vi_state == VS_MARKER)
+	if (! VSTATE_VALID(vip->vi_state))
 		vnpanic(vp, "state is %s at %s:%d",
 		    vstate_name(vip->vi_state), func, line);
 
-	while (vip->vi_state != VS_ACTIVE && vip->vi_state != VS_RECLAIMED)
+	while (vip->vi_state != VS_LOADED && vip->vi_state != VS_RECLAIMED)
 		cv_wait(&vp->v_cv, vp->v_interlock);
 
-	if (vip->vi_state == VS_MARKER)
+	if (! VSTATE_VALID(vip->vi_state))
 		vnpanic(vp, "state is %s at %s:%d",
 		    vstate_name(vip->vi_state), func, line);
 }
@@ -294,10 +298,10 @@ vstate_assert_change(vnode_t *vp, enum v
 	if (from == VS_LOADING)
 		KASSERTMSG(mutex_owned(&vcache_lock), "at %s:%d", func, line);
 
-	if (from == VS_MARKER)
+	if (! VSTATE_VALID(from))
 		vnpanic(vp, "from is %s at %s:%d",
 		    vstate_name(from), func, line);
-	if (to == VS_MARKER)
+	if (! VSTATE_VALID(to))
 		vnpanic(vp, "to is %s at %s:%d",
 		    vstate_name(to), func, line);
 	if (vip->vi_state != from)
@@ -311,7 +315,7 @@ vstate_assert_change(vnode_t *vp, enum v
 	vip->vi_state = to;
 	if (from == VS_LOADING)
 		cv_broadcast(&vcache_cv);
-	if (to == VS_ACTIVE || to == VS_RECLAIMED)
+	if (to == VS_LOADED || to == VS_RECLAIMED)
 		cv_broadcast(&vp->v_cv);
 }
 
@@ -323,14 +327,18 @@ vstate_assert_change(vnode_t *vp, enum v
 	vstate_change((vp), (from), (to))
 #define VSTATE_WAIT_STABLE(vp) \
 	vstate_wait_stable((vp))
-#define VSTATE_ASSERT(vp, state)
+void
+_vstate_assert(vnode_t *vp, enum vnode_state state, const char *func, int line)
+{
+
+}
 
 static void
 vstate_wait_stable(vnode_t *vp)
 {
 	vnode_impl_t *vip = VNODE_TO_VIMPL(vp);
 
-	while (vip->vi_state != VS_ACTIVE && vip->vi_state != VS_RECLAIMED)
+	while (vip->vi_state != VS_LOADED && vip->vi_state != VS_RECLAIMED)
 		cv_wait(&vp->v_cv, vp->v_interlock);
 }
 
@@ -342,7 +350,7 @@ vstate_change(vnode_t *vp, enum vnode_st
 	vip->vi_state = to;
 	if (from == VS_LOADING)
 		cv_broadcast(&vcache_cv);
-	if (to == VS_ACTIVE || to == VS_RECLAIMED)
+	if (to == VS_LOADED || to == VS_RECLAIMED)
 		cv_broadcast(&vp->v_cv);
 }
 
@@ -528,7 +536,7 @@ vdrain_remove(vnode_t *vp)
 	if (!mutex_tryenter(vp->v_interlock))
 		return;
 	/* Probe usecount and state. */
-	if (vp->v_usecount > 0 || VSTATE_GET(vp) != VS_ACTIVE) {
+	if (vp->v_usecount > 0 || VSTATE_GET(vp) != VS_LOADED) {
 		mutex_exit(vp->v_interlock);
 		return;
 	}
@@ -752,7 +760,7 @@ vrelel(vnode_t *vp, int flags)
 	if (VSTATE_GET(vp) == VS_RECLAIMED) {
 		VOP_UNLOCK(vp);
 	} else {
-		VSTATE_CHANGE(vp, VS_ACTIVE, VS_BLOCKED);
+		VSTATE_CHANGE(vp, VS_LOADED, VS_BLOCKED);
 		mutex_exit(vp->v_interlock);
 
 		/*
@@ -768,7 +776,7 @@ vrelel(vnode_t *vp, int flags)
 		if (!recycle)
 			VOP_UNLOCK(vp);
 		mutex_enter(vp->v_interlock);
-		VSTATE_CHANGE(vp, VS_BLOCKED, VS_ACTIVE);
+		VSTATE_CHANGE(vp, VS_BLOCKED, VS_LOADED);
 		if (!recycle) {
 			if (vtryrele(vp)) {
 				mutex_exit(vp->v_interlock);
@@ -791,7 +799,7 @@ vrelel(vnode_t *vp, int flags)
 		 * otherwise just free it.
 		 */
 		if (recycle) {
-			VSTATE_ASSERT(vp, VS_ACTIVE);
+			VSTATE_ASSERT(vp, VS_LOADED);
 			/* vcache_reclaim drops the lock. */
 			vcache_reclaim(vp);
 		}
@@ -910,14 +918,14 @@ vrecycle(vnode_t *vp)
 	}
 
 	/* If the vnode is already clean we're done. */
-	if (VSTATE_GET(vp) != VS_ACTIVE) {
+	if (VSTATE_GET(vp) != VS_LOADED) {
 		VSTATE_ASSERT(vp, VS_RECLAIMED);
 		vrelel(vp, 0);
 		return true;
 	}
 
 	/* Prevent further references until the vnode is locked. */
-	VSTATE_CHANGE(vp, VS_ACTIVE, VS_BLOCKED);
+	VSTATE_CHANGE(vp, VS_LOADED, VS_BLOCKED);
 	mutex_exit(vp->v_interlock);
 
 	/*
@@ -929,7 +937,7 @@ vrecycle(vnode_t *vp)
 	error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY | LK_NOWAIT);
 
 	mutex_enter(vp->v_interlock);
-	VSTATE_CHANGE(vp, VS_BLOCKED, VS_ACTIVE);
+	VSTATE_CHANGE(vp, VS_BLOCKED, VS_LOADED);
 
 	if (error) {
 		mutex_exit(vp->v_interlock);
@@ -1024,7 +1032,7 @@ vgone(vnode_t *vp)
 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 	mutex_enter(vp->v_interlock);
 	VSTATE_WAIT_STABLE(vp);
-	if (VSTATE_GET(vp) == VS_ACTIVE)
+	if (VSTATE_GET(vp) == VS_LOADED)
 		vcache_reclaim(vp);
 	VSTATE_ASSERT(vp, VS_RECLAIMED);
 	vrelel(vp, 0);
@@ -1199,7 +1207,7 @@ vcache_tryvget(vnode_t *vp)
 
 	if (__predict_false(VSTATE_GET(vp) == VS_RECLAIMED))
 		error = ENOENT;
-	else if (__predict_false(VSTATE_GET(vp) != VS_ACTIVE))
+	else if (__predict_false(VSTATE_GET(vp) != VS_LOADED))
 		error = EBUSY;
 	else if (vp->v_usecount == 0)
 		vp->v_usecount = 1;
@@ -1237,7 +1245,7 @@ vcache_vget(vnode_t *vp)
 			mutex_exit(vp->v_interlock);
 		return ENOENT;
 	}
-	VSTATE_ASSERT(vp, VS_ACTIVE);
+	VSTATE_ASSERT(vp, VS_LOADED);
 	if (vp->v_usecount == 0)
 		vp->v_usecount = 1;
 	else
@@ -1349,7 +1357,7 @@ again:
 	mutex_enter(&vcache_lock);
 	new_vip->vi_key.vk_key = new_key;
 	mutex_enter(vp->v_interlock);
-	VSTATE_CHANGE(vp, VS_LOADING, VS_ACTIVE);
+	VSTATE_CHANGE(vp, VS_LOADING, VS_LOADED);
 	mutex_exit(vp->v_interlock);
 	mutex_exit(&vcache_lock);
 	*vpp = vp;
@@ -1414,7 +1422,7 @@ vcache_new(struct mount *mp, struct vnod
 	/* Finished loading, finalize node. */
 	mutex_enter(&vcache_lock);
 	mutex_enter(vp->v_interlock);
-	VSTATE_CHANGE(vp, VS_LOADING, VS_ACTIVE);
+	VSTATE_CHANGE(vp, VS_LOADING, VS_LOADED);
 	mutex_exit(&vcache_lock);
 	mutex_exit(vp->v_interlock);
 	*vpp = vp;
@@ -1549,7 +1557,7 @@ vcache_reclaim(vnode_t *vp)
 	 * Prevent the vnode from being recycled or brought into use
 	 * while we clean it out.
 	 */
-	VSTATE_CHANGE(vp, VS_ACTIVE, VS_RECLAIMING);
+	VSTATE_CHANGE(vp, VS_LOADED, VS_RECLAIMING);
 	if (vp->v_iflag & VI_EXECMAP) {
 		atomic_add_int(&uvmexp.execpages, -vp->v_uobj.uo_npages);
 		atomic_add_int(&uvmexp.filepages, vp->v_uobj.uo_npages);

Index: src/sys/sys/vnode_impl.h
diff -u src/sys/sys/vnode_impl.h:1.13 src/sys/sys/vnode_impl.h:1.14
--- src/sys/sys/vnode_impl.h:1.13	Thu Mar 30 09:16:53 2017
+++ src/sys/sys/vnode_impl.h	Sun Jun  4 07:58:30 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: vnode_impl.h,v 1.13 2017/03/30 09:16:53 hannken Exp $	*/
+/*	$NetBSD: vnode_impl.h,v 1.14 2017/06/04 07:58:30 hannken Exp $	*/
 
 /*-
  * Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -37,9 +37,10 @@
 struct namecache;
 
 enum vnode_state {
+	VS_ACTIVE,	/* Assert only, fs node attached and usecount > 0. */
 	VS_MARKER,	/* Stable, used as marker. Will not change. */
 	VS_LOADING,	/* Intermediate, initialising the fs node. */
-	VS_ACTIVE,	/* Stable, valid fs node attached. */
+	VS_LOADED,	/* Stable, valid fs node attached. */
 	VS_BLOCKED,	/* Intermediate, active, no new references allowed. */
 	VS_RECLAIMING,	/* Intermediate, detaching the fs node. */
 	VS_RECLAIMED	/* Stable, no fs node attached. */
@@ -85,6 +86,31 @@ typedef struct vnode_impl vnode_impl_t;
 #define VNODE_TO_VIMPL(vp)	container_of((vp), struct vnode_impl, vi_vnode)
 
 /*
+ * Vnode state assertion.
+ */
+void _vstate_assert(vnode_t *, enum vnode_state, const char *, int );
+
+#if defined(DIAGNOSTIC) 
+
+#define VSTATE_ASSERT(vp, state) \
+	do { \
+		_vstate_assert((vp), (state), __func__, __LINE__); \
+	} while (/*CONSTCOND*/ 0)
+#define VSTATE_ASSERT_UNLOCKED(vp, state) \
+	do { \
+		mutex_enter((vp)->v_interlock); \
+		_vstate_assert((vp), (state), __func__, __LINE__); \
+		mutex_exit((vp)->v_interlock); \
+	} while (/*CONSTCOND*/ 0)
+
+#else /* defined(DIAGNOSTIC) */
+
+#define VSTATE_ASSERT(vp, state)
+#define VSTATE_ASSERT_UNLOCKED(vp, state)
+
+#endif /* defined(DIAGNOSTIC) */
+
+/*
  * Vnode manipulation functions.
  */
 const char *

Reply via email to