Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/miscfs/union Fix PR5146: reboot with working directory i...
details: https://anonhg.NetBSD.org/src/rev/223fbe0314cc
branches: trunk
changeset: 475093:223fbe0314cc
user: sommerfeld <sommerfeld%NetBSD.org@localhost>
date: Sun Aug 01 00:00:57 1999 +0000
description:
Fix PR5146: reboot with working directory in unionfs causes
"panic: lockmgr: using decommisioned lock"
(only if DIAGNOSTIC)
The problem turned out to be due to the way LK_DRAIN was (not) handled
in union_lock; it just got passed through to the lock on the upper
vnode (which got marked as decommissioned, instead of that happening
to the union vnode. When the upper vnode was next locked (typically
when it was released), it went kaboom.
diffstat:
sys/miscfs/union/union.h | 4 +++-
sys/miscfs/union/union_vnops.c | 40 ++++++++++++++++++++++++++++++++++++++--
2 files changed, 41 insertions(+), 3 deletions(-)
diffs (107 lines):
diff -r 2adc2e83ec33 -r 223fbe0314cc sys/miscfs/union/union.h
--- a/sys/miscfs/union/union.h Sat Jul 31 23:56:15 1999 +0000
+++ b/sys/miscfs/union/union.h Sun Aug 01 00:00:57 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: union.h,v 1.10 1997/05/05 07:14:02 mycroft Exp $ */
+/* $NetBSD: union.h,v 1.11 1999/08/01 00:00:57 sommerfeld Exp $ */
/*
* Copyright (c) 1994 The Regents of the University of California.
@@ -92,6 +92,8 @@
#define UN_ULOCK 0x04 /* Upper node is locked */
#define UN_KLOCK 0x08 /* Keep upper node locked on vput */
#define UN_CACHED 0x10 /* In union cache */
+#define UN_DRAINING 0x20 /* upper node lock is draining */
+#define UN_DRAINED 0x40 /* upper node lock is drained */
extern int union_allocvp __P((struct vnode **, struct mount *,
struct vnode *, struct vnode *,
diff -r 2adc2e83ec33 -r 223fbe0314cc sys/miscfs/union/union_vnops.c
--- a/sys/miscfs/union/union_vnops.c Sat Jul 31 23:56:15 1999 +0000
+++ b/sys/miscfs/union/union_vnops.c Sun Aug 01 00:00:57 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: union_vnops.c,v 1.44 1999/03/25 13:05:42 bouyer Exp $ */
+/* $NetBSD: union_vnops.c,v 1.45 1999/08/01 00:00:57 sommerfeld Exp $ */
/*
* Copyright (c) 1992, 1993, 1994, 1995 Jan-Simon Pendry.
@@ -1595,7 +1595,9 @@
int flags = ap->a_flags;
struct union_node *un;
int error;
-
+#ifdef DIAGNOSTIC
+ int drain = 0;
+#endif
genfs_nolock(ap);
/*
@@ -1609,6 +1611,31 @@
*/
flags &= ~LK_INTERLOCK;
+ un = VTOUNION(vp);
+#ifdef DIAGNOSTIC
+ if (un->un_flags & (UN_DRAINING|UN_DRAINED)) {
+ if (un->un_flags & UN_DRAINED)
+ panic("union: %p: warning: locking decommissioned lock\n", vp);
+ if ((flags & LK_TYPE_MASK) != LK_RELEASE)
+ panic("union: %p: non-release on draining lock: %d\n",
+ vp, flags & LK_TYPE_MASK);
+ un->un_flags &= ~UN_DRAINING;
+ if ((flags & LK_REENABLE) == 0)
+ un->un_flags |= UN_DRAINED;
+ }
+#endif
+
+ /*
+ * Don't pass DRAIN through to sub-vnode lock; keep track of
+ * DRAIN state at this level, and just get an exclusive lock
+ * on the underlying vnode.
+ */
+ if ((flags & LK_TYPE_MASK) == LK_DRAIN) {
+#ifdef DIAGNOSTIC
+ drain = 1;
+#endif
+ flags = LK_EXCLUSIVE | (flags & ~LK_TYPE_MASK);
+ }
start:
un = VTOUNION(vp);
@@ -1633,6 +1660,7 @@
#endif
}
+ /* XXX ignores LK_NOWAIT */
if (un->un_flags & UN_LOCKED) {
#ifdef DIAGNOSTIC
if (curproc && un->un_pid == curproc->p_pid &&
@@ -1649,6 +1677,8 @@
un->un_pid = curproc->p_pid;
else
un->un_pid = -1;
+ if (drain)
+ un->un_flags |= UN_DRAINING;
#endif
un->un_flags |= UN_LOCKED;
@@ -1682,6 +1712,8 @@
if (curproc && un->un_pid != curproc->p_pid &&
curproc->p_pid > -1 && un->un_pid > -1)
panic("union: unlocking other process's union node");
+ if (un->un_flags & UN_DRAINED)
+ panic("union: %p: warning: unlocking decommissioned lock\n", ap->a_vp);
#endif
un->un_flags &= ~UN_LOCKED;
@@ -1698,6 +1730,10 @@
#ifdef DIAGNOSTIC
un->un_pid = 0;
+ if (un->un_flags & UN_DRAINING) {
+ un->un_flags |= UN_DRAINED;
+ un->un_flags &= ~UN_DRAINING;
+ }
#endif
genfs_nounlock(ap);
Home |
Main Index |
Thread Index |
Old Index