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 *