summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authoranton <anton@cvs.openbsd.org>2018-10-27 08:51:14 +0000
committeranton <anton@cvs.openbsd.org>2018-10-27 08:51:14 +0000
commit4f80a7c08474c49c28c68216a6ab17e4c016ee6d (patch)
treefcdfb63e73c1a2ddbb05a131d200e2f19e41617d /sys/kern
parent03a582a3a1ee6ade39264858ccd0f6b3b1790984 (diff)
Add assertions for lockf list manipulation, hidden behind LOCKF_DIAGNOSTIC.
While here, improve existing lockf debug routines and sprinkle some more logging related to list manipulation. ok deraadt@ visa@ (as part of a larger diff)
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/vfs_lockf.c76
1 files changed, 61 insertions, 15 deletions
diff --git a/sys/kern/vfs_lockf.c b/sys/kern/vfs_lockf.c
index 9a2e3ea7d8f..e73ab4dbe33 100644
--- a/sys/kern/vfs_lockf.c
+++ b/sys/kern/vfs_lockf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_lockf.c,v 1.27 2018/10/27 08:47:09 anton Exp $ */
+/* $OpenBSD: vfs_lockf.c,v 1.28 2018/10/27 08:51:13 anton Exp $ */
/* $NetBSD: vfs_lockf.c,v 1.7 1996/02/04 02:18:21 christos Exp $ */
/*
@@ -64,12 +64,15 @@ int maxlockdepth = MAXDEPTH;
#define DEBUG_FINDOVR 0x08
#define DEBUG_SPLIT 0x10
#define DEBUG_WAKELOCK 0x20
+#define DEBUG_LINK 0x80
int lockf_debug = DEBUG_SETLOCK|DEBUG_CLEARLOCK|DEBUG_WAKELOCK;
#define DPRINTF(args, level) if (lockf_debug & (level)) printf args
+#define LFPRINT(args, level) if (lockf_debug & (level)) lf_print args
#else
#define DPRINTF(args, level)
+#define LFPRINT(args, level)
#endif
void
@@ -122,10 +125,22 @@ lf_free(struct lockf *lock)
{
struct uidinfo *uip;
+ LFPRINT(("lf_free", lock), DEBUG_LINK);
+
if (*lock->lf_head == lock) {
+ LFPRINT(("lf_free: head", lock->lf_next), DEBUG_LINK);
+
+#ifdef LOCKF_DIAGNOSTIC
+ KASSERT(lock->lf_prev == NULL);
+#endif /* LOCKF_DIAGNOSTIC */
+
*lock->lf_head = lock->lf_next;
}
+#ifdef LOCKF_DIAGNOSTIC
+ KASSERT(TAILQ_EMPTY(&lock->lf_blkhd));
+#endif /* LOCKF_DIAGNOSTIC */
+
lf_unlink(lock);
uip = uid_find(lock->lf_uid);
@@ -137,6 +152,18 @@ lf_free(struct lockf *lock)
void
lf_link(struct lockf *lock1, struct lockf *lock2)
{
+ LFPRINT(("lf_link: lock1", lock1), DEBUG_LINK);
+ LFPRINT(("lf_link: lock2", lock2), DEBUG_LINK);
+
+#ifdef LOCKF_DIAGNOSTIC
+ KASSERT(lock1 != NULL && lock2 != NULL);
+ KASSERT(lock1 != lock2);
+ if (lock1->lf_next != NULL)
+ KASSERT(lock2->lf_next == NULL);
+ if (lock2->lf_prev != NULL)
+ KASSERT(lock1->lf_prev == NULL);
+#endif /* LOCKF_DIAGNOSTIC */
+
if (lock1->lf_next != NULL) {
lock2->lf_next = lock1->lf_next;
lock1->lf_next->lf_prev = lock2;
@@ -150,8 +177,16 @@ lf_link(struct lockf *lock1, struct lockf *lock2)
lock2->lf_prev = lock1;
if (*lock1->lf_head == NULL) {
+ LFPRINT(("lf_link: head", lock1), DEBUG_LINK);
+
+#ifdef LOCKF_DIAGNOSTIC
+ KASSERT(*lock2->lf_head == NULL);
+#endif /* LOCKF_DIAGNOSTIC */
+
*lock1->lf_head = lock1;
} else if (*lock2->lf_head == lock2) {
+ LFPRINT(("lf_link: swap head", lock1), DEBUG_LINK);
+
*lock1->lf_head = lock1;
}
}
@@ -159,6 +194,8 @@ lf_link(struct lockf *lock1, struct lockf *lock2)
void
lf_unlink(struct lockf *lock)
{
+ LFPRINT(("lf_unlink", lock), DEBUG_LINK);
+
if (lock->lf_prev != NULL)
lock->lf_prev->lf_next = lock->lf_next;
if (lock->lf_next != NULL)
@@ -731,8 +768,15 @@ void
lf_print(char *tag, struct lockf *lock)
{
struct lockf *block;
-
- printf("%s: lock %p for ", tag, lock);
+
+ if (tag)
+ printf("%s: ", tag);
+ printf("lock %p", lock);
+ if (lock == NULL) {
+ printf("\n");
+ return;
+ }
+ printf(" for ");
if (lock->lf_flags & F_POSIX)
printf("thread %d", ((struct proc *)(lock->lf_id))->p_tid);
else
@@ -742,33 +786,35 @@ lf_print(char *tag, struct lockf *lock)
lock->lf_type == F_WRLCK ? "exclusive" :
lock->lf_type == F_UNLCK ? "unlock" :
"unknown", lock->lf_start, lock->lf_end);
+ printf(", prev %p, next %p", lock->lf_prev, lock->lf_next);
block = TAILQ_FIRST(&lock->lf_blkhd);
if (block)
- printf(" block");
+ printf(", block");
TAILQ_FOREACH(block, &lock->lf_blkhd, lf_block)
printf(" %p,", block);
printf("\n");
-
}
void
lf_printlist(char *tag, struct lockf *lock)
{
struct lockf *lf;
+#ifdef LOCKF_DIAGNOSTIC
+ struct lockf *prev = NULL;
+#endif /* LOCKF_DIAGNOSTIC */
printf("%s: Lock list:\n", tag);
for (lf = *lock->lf_head; lf; lf = lf->lf_next) {
- printf("\tlock %p for ", lf);
- if (lf->lf_flags & F_POSIX)
- printf("thread %d", ((struct proc*)(lf->lf_id))->p_tid);
+ if (lock == lf)
+ printf(" * ");
else
- printf("id %p", lf->lf_id);
- printf(" %s, start %llx, end %llx",
- lf->lf_type == F_RDLCK ? "shared" :
- lf->lf_type == F_WRLCK ? "exclusive" :
- lf->lf_type == F_UNLCK ? "unlock" :
- "unknown", lf->lf_start, lf->lf_end);
- printf("\n");
+ printf(" ");
+ lf_print(NULL, lf);
+
+#ifdef LOCKF_DIAGNOSTIC
+ KASSERT(lf->lf_prev == prev);
+ prev = lf;
+#endif /* LOCKF_DIAGNOSTIC */
}
}
#endif /* LOCKF_DEBUG */