summaryrefslogtreecommitdiffstats
path: root/sys/miscfs/union
diff options
context:
space:
mode:
authorkato <kato@FreeBSD.org>1998-02-10 03:32:07 +0000
committerkato <kato@FreeBSD.org>1998-02-10 03:32:07 +0000
commit50af713bea84392927504d5a94f3ca83271b5946 (patch)
tree0e7101898990483565ae6b38b3fba7e769536ecc /sys/miscfs/union
parent0c1ad0fcbbe4368c531b3e63d49f7288a2ff8549 (diff)
downloadFreeBSD-src-50af713bea84392927504d5a94f3ca83271b5946.zip
FreeBSD-src-50af713bea84392927504d5a94f3ca83271b5946.tar.gz
Undo UN_KLOCK hack except union_allocvp(). Now, vput() doesn't lock
the vnode.
Diffstat (limited to 'sys/miscfs/union')
-rw-r--r--sys/miscfs/union/union.h7
-rw-r--r--sys/miscfs/union/union_subr.c8
-rw-r--r--sys/miscfs/union/union_vnops.c71
3 files changed, 32 insertions, 54 deletions
diff --git a/sys/miscfs/union/union.h b/sys/miscfs/union/union.h
index f3bbb89..442fc95 100644
--- a/sys/miscfs/union/union.h
+++ b/sys/miscfs/union/union.h
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* @(#)union.h 8.9 (Berkeley) 12/10/94
- * $Id: union.h,v 1.9 1997/11/18 15:07:34 phk Exp $
+ * $Id: union.h,v 1.10 1998/01/20 10:02:50 kato Exp $
*/
struct union_args {
@@ -93,9 +93,10 @@ struct union_node {
#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_GLOCK 0x20 /* Keep upper node locked on vget */
-#define SETKLOCK(un) (un)->un_flags |= UN_KLOCK
-#define CLEARKLOCK(un) (un)->un_flags &= ~UN_KLOCK
+#define SETGLOCK(un) (un)->un_flags |= UN_GLOCK
+#define CLEARGLOCK(un) (un)->un_flags &= ~UN_GLOCK
extern int union_allocvp __P((struct vnode **, struct mount *,
struct vnode *, struct vnode *,
diff --git a/sys/miscfs/union/union_subr.c b/sys/miscfs/union/union_subr.c
index f7f82c2..8ba3d87 100644
--- a/sys/miscfs/union/union_subr.c
+++ b/sys/miscfs/union/union_subr.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* @(#)union_subr.c 8.20 (Berkeley) 5/20/95
- * $Id: union_subr.c,v 1.26 1998/02/04 22:32:52 eivind Exp $
+ * $Id: union_subr.c,v 1.27 1998/02/06 12:13:44 eivind Exp $
*/
#include <sys/param.h>
@@ -370,7 +370,7 @@ loop:
*/
if ((un->un_uppervp != NULLVP) &&
((un->un_flags & UN_KLOCK) == 0)) {
- SETKLOCK(un);
+ SETGLOCK(un);
klocked = 1;
} else {
klocked = 0;
@@ -378,12 +378,12 @@ loop:
if (vget(UNIONTOV(un), 0,
cnp ? cnp->cn_proc : NULL)) {
if (klocked)
- CLEARKLOCK(un);
+ CLEARGLOCK(un);
union_list_unlock(hash);
goto loop;
}
if (klocked)
- CLEARKLOCK(un);
+ CLEARGLOCK(un);
break;
}
}
diff --git a/sys/miscfs/union/union_vnops.c b/sys/miscfs/union/union_vnops.c
index fc485f3..c54dcce 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.52 1998/02/06 02:42:21 kato Exp $
+ * $Id: union_vnops.c,v 1.53 1998/02/06 12:13:44 eivind Exp $
*/
#include <sys/param.h>
@@ -266,9 +266,8 @@ union_lookup(ap)
*/
if (cnp->cn_flags & ISDOTDOT) {
/* retain lock on underlying VP: */
- SETKLOCK(dun);
+ dun->un_flags |= UN_KLOCK;
VOP_UNLOCK(dvp, 0, p);
- CLEARKLOCK(dun);
}
uerror = union_lookup1(um->um_uppervp, &upperdvp,
&uppervp, cnp);
@@ -504,10 +503,9 @@ union_create(ap)
FIXUP(un, p);
VREF(dvp);
- SETKLOCK(un);
+ un->un_flags |= UN_KLOCK;
mp = ap->a_dvp->v_mount;
vput(ap->a_dvp);
- CLEARKLOCK(un);
error = VOP_CREATE(dvp, &vp, cnp, ap->a_vap);
if (error)
return (error);
@@ -564,10 +562,9 @@ union_mknod(ap)
FIXUP(un, p);
VREF(dvp);
- SETKLOCK(un);
+ un->un_flags |= UN_KLOCK;
mp = ap->a_dvp->v_mount;
vput(ap->a_dvp);
- CLEARKLOCK(un);
error = VOP_MKNOD(dvp, &vp, cnp, ap->a_vap);
if (error)
return (error);
@@ -1073,14 +1070,12 @@ union_remove(ap)
FIXUP(dun, p);
VREF(dvp);
- SETKLOCK(dun);
+ dun->un_flags |= UN_KLOCK;
vput(ap->a_dvp);
- CLEARKLOCK(dun);
FIXUP(un, p);
VREF(vp);
- SETKLOCK(un);
+ un->un_flags |= UN_KLOCK;
vput(ap->a_vp);
- CLEARKLOCK(un);
if (union_dowhiteout(un, cnp->cn_cred, cnp->cn_proc))
cnp->cn_flags |= DOWHITEOUT;
@@ -1151,9 +1146,8 @@ union_link(ap)
FIXUP(un, p);
VREF(tdvp);
- SETKLOCK(un);
+ un->un_flags |= UN_KLOCK;
vput(ap->a_tdvp);
- CLEARKLOCK(un);
return (VOP_LINK(tdvp, vp, cnp));
}
@@ -1175,7 +1169,6 @@ union_rename(ap)
struct vnode *fvp = ap->a_fvp;
struct vnode *tdvp = ap->a_tdvp;
struct vnode *tvp = ap->a_tvp;
- int isklockset = 0;
if (fdvp->v_op == union_vnodeop_p) { /* always true */
struct union_node *un = VTOUNION(fdvp);
@@ -1226,9 +1219,8 @@ union_rename(ap)
tdvp = un->un_uppervp;
VREF(tdvp);
- SETKLOCK(un);
+ un->un_flags |= UN_KLOCK;
vput(ap->a_tdvp);
- CLEARKLOCK(un);
}
if (tvp != NULLVP && tvp->v_op == union_vnodeop_p) {
@@ -1237,12 +1229,9 @@ union_rename(ap)
tvp = un->un_uppervp;
if (tvp != NULLVP) {
VREF(tvp);
- SETKLOCK(un);
- isklockset = 1;
+ un->un_flags |= UN_KLOCK;
}
vput(ap->a_tvp);
- if (isklockset)
- CLEARKLOCK(un);
}
return (VOP_RENAME(fdvp, fvp, ap->a_fcnp, tdvp, tvp, ap->a_tcnp));
@@ -1277,9 +1266,8 @@ union_mkdir(ap)
FIXUP(un, p);
VREF(dvp);
- SETKLOCK(un);
+ un->un_flags |= UN_KLOCK;
VOP_UNLOCK(ap->a_dvp, 0, p);
- CLEARKLOCK(un);
error = VOP_MKDIR(dvp, &vp, cnp, ap->a_vap);
if (error) {
vrele(ap->a_dvp);
@@ -1321,14 +1309,12 @@ union_rmdir(ap)
FIXUP(dun, p);
VREF(dvp);
- SETKLOCK(dun);
+ dun->un_flags |= UN_KLOCK;
vput(ap->a_dvp);
- CLEARKLOCK(dun);
FIXUP(un, p);
VREF(vp);
- SETKLOCK(un);
+ un->un_flags |= UN_KLOCK;
vput(ap->a_vp);
- CLEARKLOCK(un);
if (union_dowhiteout(un, cnp->cn_cred, cnp->cn_proc))
cnp->cn_flags |= DOWHITEOUT;
@@ -1371,9 +1357,8 @@ union_symlink(ap)
FIXUP(un, p);
VREF(dvp);
- SETKLOCK(un);
+ un->un_flags |= UN_KLOCK;
vput(ap->a_dvp);
- CLEARKLOCK(un);
error = VOP_SYMLINK(dvp, &vp, cnp, ap->a_vap, ap->a_target);
*ap->a_vpp = NULLVP;
return (error);
@@ -1548,13 +1533,19 @@ start:
if (un->un_uppervp != NULLVP) {
if (((un->un_flags & UN_ULOCK) == 0) &&
(vp->v_usecount != 0)) {
- if ((un->un_flags & UN_KLOCK) == 0) {
+ if ((un->un_flags & UN_GLOCK) == 0) {
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) {
+ vprint("dangling upper lock", vp);
+ panic("union: dangling upper lock");
+ }
+#endif
}
if (un->un_flags & UN_LOCKED) {
@@ -1590,10 +1581,6 @@ start:
*
* If UN_KLOCK isn't set, then the upper vnode is unlocked here.
*/
-/*
- * FreeBSD: Do not cleark UN_KLOCK flag. UN_KLOCK flag is tested
- * in union_lock().
- */
static int
union_unlock(ap)
struct vop_unlock_args /* {
@@ -1615,20 +1602,10 @@ union_unlock(ap)
un->un_flags &= ~UN_LOCKED;
- if ((un->un_flags & (UN_ULOCK|UN_KLOCK)) == UN_ULOCK) {
- /*
- * XXX
- * Workarround for lockmgr violation. Need to implement
- * real lockmgr-style lock/unlock.
- */
- if ((ap->a_vp->v_flag & VDOOMED) &&
- ((struct lock *)un->un_uppervp->v_data)->lk_lockholder
- == LK_KERNPROC)
- VOP_UNLOCK(un->un_uppervp, 0, 0);
- else
- VOP_UNLOCK(un->un_uppervp, 0, p);
- }
- un->un_flags &= ~UN_ULOCK;
+ if ((un->un_flags & (UN_ULOCK|UN_KLOCK|UN_GLOCK)) == UN_ULOCK)
+ VOP_UNLOCK(un->un_uppervp, 0, p);
+
+ un->un_flags &= ~(UN_ULOCK|UN_KLOCK);
if (un->un_flags & UN_WANT) {
un->un_flags &= ~UN_WANT;
OpenPOWER on IntegriCloud