diff options
author | kato <kato@FreeBSD.org> | 1997-04-21 15:32:24 +0000 |
---|---|---|
committer | kato <kato@FreeBSD.org> | 1997-04-21 15:32:24 +0000 |
commit | e696227ac203e92da4484d6623548add5ecd1071 (patch) | |
tree | fc9ddea76a68728f68153ff6c3757990314159e1 /sys/miscfs | |
parent | 271384e50bbdafb56a07356fd164e6cd09eff68e (diff) | |
download | FreeBSD-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.c | 28 |
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) { |