Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern Add vnode state and supporting operations and diagn...
details: https://anonhg.NetBSD.org/src/rev/f96e3ae9ff1f
branches: trunk
changeset: 345429:f96e3ae9ff1f
user: hannken <hannken%NetBSD.org@localhost>
date: Thu May 26 11:08:44 2016 +0000
description:
Add vnode state and supporting operations and diagnostics.
Presented on tech-kern@
diffstat:
sys/kern/vfs_vnode.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 155 insertions(+), 3 deletions(-)
diffs (221 lines):
diff -r f4bc1a5e99d1 -r f96e3ae9ff1f sys/kern/vfs_vnode.c
--- a/sys/kern/vfs_vnode.c Thu May 26 11:07:33 2016 +0000
+++ b/sys/kern/vfs_vnode.c Thu May 26 11:08:44 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_vnode.c,v 1.50 2016/05/26 11:07:33 hannken Exp $ */
+/* $NetBSD: vfs_vnode.c,v 1.51 2016/05/26 11:08:44 hannken Exp $ */
/*-
* Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -116,7 +116,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.50 2016/05/26 11:07:33 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.51 2016/05/26 11:08:44 hannken Exp $");
#define _VFS_VNODE_PRIVATE
@@ -148,6 +148,14 @@
#define VRELEL_ASYNC_RELE 0x0001 /* Always defer to vrele thread. */
#define VRELEL_CHANGING_SET 0x0002 /* VI_CHANGING set by caller. */
+enum vcache_state {
+ VN_MARKER, /* Stable, used as marker. Will not change. */
+ VN_LOADING, /* Intermediate, initialising the fs node. */
+ VN_ACTIVE, /* Stable, valid fs node attached. */
+ VN_BLOCKED, /* Intermediate, active, no new references allowed. */
+ VN_RECLAIMING, /* Intermediate, detaching the fs node. */
+ VN_RECLAIMED /* Stable, no fs node attached. */
+};
struct vcache_key {
struct mount *vk_mount;
const void *vk_key;
@@ -155,6 +163,7 @@
};
struct vcache_node {
struct vnode vn_data;
+ enum vcache_state vn_state;
SLIST_ENTRY(vcache_node) vn_hash;
struct vnode *vn_vnode;
struct vcache_key vn_key;
@@ -185,6 +194,7 @@
SLIST_HEAD(hashhead, vcache_node);
static struct {
kmutex_t lock;
+ kcondvar_t cv;
u_long hashmask;
struct hashhead *hashtab;
pool_cache_t pool;
@@ -208,6 +218,145 @@
extern int (**dead_vnodeop_p)(void *);
extern struct vfsops dead_vfsops;
+/* Vnode state operations and diagnostics. */
+
+static const char *
+vstate_name(enum vcache_state state)
+{
+
+ switch (state) {
+ case VN_MARKER:
+ return "MARKER";
+ case VN_LOADING:
+ return "LOADING";
+ case VN_ACTIVE:
+ return "ACTIVE";
+ case VN_BLOCKED:
+ return "BLOCKED";
+ case VN_RECLAIMING:
+ return "RECLAIMING";
+ case VN_RECLAIMED:
+ return "RECLAIMED";
+ default:
+ return "ILLEGAL";
+ }
+}
+
+#if defined(DIAGNOSTIC)
+
+#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 __unused
+vstate_assert(vnode_t *vp, enum vcache_state state, const char *func, int line)
+{
+ struct vcache_node *node = VP_TO_VN(vp);
+
+ KASSERTMSG(mutex_owned(vp->v_interlock), "at %s:%d", func, line);
+
+ if (__predict_true(node->vn_state == state))
+ return;
+ vnpanic(vp, "state is %s, expected %s at %s:%d",
+ vstate_name(node->vn_state), vstate_name(state), func, line);
+}
+
+static enum vcache_state __unused
+vstate_assert_get(vnode_t *vp, const char *func, int line)
+{
+ struct vcache_node *node = VP_TO_VN(vp);
+
+ KASSERTMSG(mutex_owned(vp->v_interlock), "at %s:%d", func, line);
+ if (node->vn_state == VN_MARKER)
+ vnpanic(vp, "state is %s at %s:%d",
+ vstate_name(node->vn_state), func, line);
+
+ return node->vn_state;
+}
+
+static void __unused
+vstate_assert_wait_stable(vnode_t *vp, const char *func, int line)
+{
+ struct vcache_node *node = VP_TO_VN(vp);
+
+ KASSERTMSG(mutex_owned(vp->v_interlock), "at %s:%d", func, line);
+ if (node->vn_state == VN_MARKER)
+ vnpanic(vp, "state is %s at %s:%d",
+ vstate_name(node->vn_state), func, line);
+
+ while (node->vn_state != VN_ACTIVE && node->vn_state != VN_RECLAIMED)
+ cv_wait(&vp->v_cv, vp->v_interlock);
+
+ if (node->vn_state == VN_MARKER)
+ vnpanic(vp, "state is %s at %s:%d",
+ vstate_name(node->vn_state), func, line);
+}
+
+static void __unused
+vstate_assert_change(vnode_t *vp, enum vcache_state from, enum vcache_state to,
+ const char *func, int line)
+{
+ struct vcache_node *node = VP_TO_VN(vp);
+
+ KASSERTMSG(mutex_owned(vp->v_interlock), "at %s:%d", func, line);
+ if (from == VN_LOADING)
+ KASSERTMSG(mutex_owned(&vcache.lock), "at %s:%d", func, line);
+
+ if (from == VN_MARKER)
+ vnpanic(vp, "from is %s at %s:%d",
+ vstate_name(from), func, line);
+ if (to == VN_MARKER)
+ vnpanic(vp, "to is %s at %s:%d",
+ vstate_name(to), func, line);
+ if (node->vn_state != from)
+ vnpanic(vp, "from is %s, expected %s at %s:%d\n",
+ vstate_name(node->vn_state), vstate_name(from), func, line);
+
+ node->vn_state = to;
+ if (from == VN_LOADING)
+ cv_broadcast(&vcache.cv);
+ if (to == VN_ACTIVE || to == VN_RECLAIMED)
+ cv_broadcast(&vp->v_cv);
+}
+
+#else /* defined(DIAGNOSTIC) */
+
+#define VSTATE_GET(vp) \
+ (VP_TO_VN((vp))->vn_state)
+#define VSTATE_CHANGE(vp, from, to) \
+ vstate_change((vp), (from), (to))
+#define VSTATE_WAIT_STABLE(vp) \
+ vstate_wait_stable((vp))
+#define VSTATE_ASSERT(vp, state)
+
+static void __unused
+vstate_wait_stable(vnode_t *vp)
+{
+ struct vcache_node *node = VP_TO_VN(vp);
+
+ while (node->vn_state != VN_ACTIVE && node->vn_state != VN_RECLAIMED)
+ cv_wait(&vp->v_cv, vp->v_interlock);
+}
+
+static void __unused
+vstate_change(vnode_t *vp, enum vcache_state from, enum vcache_state to)
+{
+ struct vcache_node *node = VP_TO_VN(vp);
+
+ node->vn_state = to;
+ if (from == VN_LOADING)
+ cv_broadcast(&vcache.cv);
+ if (to == VN_ACTIVE || to == VN_RECLAIMED)
+ cv_broadcast(&vp->v_cv);
+}
+
+#endif /* defined(DIAGNOSTIC) */
+
void
vfs_vnode_sysinit(void)
{
@@ -1051,6 +1200,7 @@
"vcachepl", NULL, IPL_NONE, NULL, NULL, NULL);
KASSERT(vcache.pool != NULL);
mutex_init(&vcache.lock, MUTEX_DEFAULT, IPL_NONE);
+ cv_init(&vcache.cv, "vcache");
vcache.hashtab = hashinit(desiredvnodes, HASH_SLIST, true,
&vcache.hashmask);
}
@@ -1134,6 +1284,8 @@
vp->v_type = VNON;
vp->v_size = vp->v_writesize = VSIZENOTSET;
+ node->vn_state = VN_LOADING;
+
return node;
}
@@ -1482,7 +1634,7 @@
n = node->vn_key.vk_key_len;
cp = node->vn_key.vk_key;
- (*pr)("%skey(%d)", prefix, n);
+ (*pr)("%sstate %s, key(%d)", prefix, vstate_name(node->vn_state), n);
while (n-- > 0)
(*pr)(" %02x", *cp++);
Home |
Main Index |
Thread Index |
Old Index