summaryrefslogtreecommitdiffstats
path: root/sys/miscfs
diff options
context:
space:
mode:
authorkato <kato@FreeBSD.org>1997-04-21 15:32:24 +0000
committerkato <kato@FreeBSD.org>1997-04-21 15:32:24 +0000
commite696227ac203e92da4484d6623548add5ecd1071 (patch)
treefc9ddea76a68728f68153ff6c3757990314159e1 /sys/miscfs
parent271384e50bbdafb56a07356fd164e6cd09eff68e (diff)
downloadFreeBSD-src-e696227ac203e92da4484d6623548add5ecd1071.zip
FreeBSD-src-e696227ac203e92da4484d6623548add5ecd1071.tar.gz
Dirty change in union_lock(). Sometimes upper vnode is locked without
UN_ULOCK flag. This shows a locking violation but I couldn't find the reason UN_ULOCK is not set or upper vnode is not unlocked. I added the code that detect this case and adjust un_flags. DIAGNOSTIC kernel doesn't adjust un_flags, but just panic here to help debug by kernel hackers.
Diffstat (limited to 'sys/miscfs')
-rw-r--r--sys/miscfs/union/union_vnops.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/sys/miscfs/union/union_vnops.c b/sys/miscfs/union/union_vnops.c
index 357bfc0..e90c5d49 100644
--- a/sys/miscfs/union/union_vnops.c
+++ b/sys/miscfs/union/union_vnops.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* @(#)union_vnops.c 8.32 (Berkeley) 6/23/95
- * $Id: union_vnops.c,v 1.25 1997/04/16 03:08:34 kato Exp $
+ * $Id: union_vnops.c,v 1.26 1997/04/21 12:40:42 kato Exp $
*/
#include <sys/param.h>
@@ -1477,10 +1477,28 @@ start:
if (un->un_uppervp != NULLVP) {
if (((un->un_flags & UN_ULOCK) == 0) &&
(vp->v_usecount != 0)) {
- error = vn_lock(un->un_uppervp, flags, p);
- if (error)
- return (error);
- un->un_flags |= UN_ULOCK;
+ if (VOP_ISLOCKED(un->un_uppervp)) {
+ /*
+ * XXX - Dirty!
+ * Though UN_ULOCK is not set, upper vnode is locked. This
+ * indicates a locking violation. If this case happens,
+ * we will get `lock against myself' panic.
+ *
+ * SHOULD BE FIXED! But I couldn't find a fix. If you are
+ * a kernel hacker, pleas try DIAGNOSTIC kernel, that causes
+ * panic here.
+ */
+#ifdef DIAGNOSTIC
+ panic("union_link: upper vnode is locked, "
+ "but UN_UNLOCK is not set.");
+#endif
+ un->un_flags |= UN_ULOCK; /* Adjust -- dirty */
+ } else {
+ error = vn_lock(un->un_uppervp, flags, p);
+ if (error)
+ return (error);
+ un->un_flags |= UN_ULOCK;
+ }
}
#ifdef DIAGNOSTIC
if (un->un_flags & UN_KLOCK) {
OpenPOWER on IntegriCloud