summaryrefslogtreecommitdiffstats
path: root/sys/miscfs/union
diff options
context:
space:
mode:
authorkato <kato@FreeBSD.org>1998-01-20 10:02:54 +0000
committerkato <kato@FreeBSD.org>1998-01-20 10:02:54 +0000
commitd49fde64e88ed0930d98ea5752325d23d452a74c (patch)
treef94a3f25ebb61ec2c816446513a36a8e80e7c635 /sys/miscfs/union
parent1b94ff548145fb10224df86f77d684ccfa34e93a (diff)
downloadFreeBSD-src-d49fde64e88ed0930d98ea5752325d23d452a74c.zip
FreeBSD-src-d49fde64e88ed0930d98ea5752325d23d452a74c.tar.gz
- Move SETKLOC and CLEARKLOCK macros into uion.h.
- Set UN_ULOCK in union_lock() when UN_KLOCK is set. Caller expects that vnode is locked correctly, and may call another function which expects locked vnode and may unlock the vnode. - Do not assume the behavior of inside functions in FreeBSD's vfs_suber.c is same as 4.4BSD-Lite2. Vnode may be locked in vget() even though flag is zero. (Locked vnode is, of course, unlocked before returning from vget.)
Diffstat (limited to 'sys/miscfs/union')
-rw-r--r--sys/miscfs/union/union.h5
-rw-r--r--sys/miscfs/union/union_subr.c19
-rw-r--r--sys/miscfs/union/union_vnops.c19
3 files changed, 33 insertions, 10 deletions
diff --git a/sys/miscfs/union/union.h b/sys/miscfs/union/union.h
index 03e7033..f3bbb89 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.8 1997/02/22 09:40:40 peter Exp $
+ * $Id: union.h,v 1.9 1997/11/18 15:07:34 phk Exp $
*/
struct union_args {
@@ -94,6 +94,9 @@ struct union_node {
#define UN_KLOCK 0x08 /* Keep upper node locked on vput */
#define UN_CACHED 0x10 /* In union cache */
+#define SETKLOCK(un) (un)->un_flags |= UN_KLOCK
+#define CLEARKLOCK(un) (un)->un_flags &= ~UN_KLOCK
+
extern int union_allocvp __P((struct vnode **, struct mount *,
struct vnode *, struct vnode *,
struct componentname *, struct vnode *,
diff --git a/sys/miscfs/union/union_subr.c b/sys/miscfs/union/union_subr.c
index 3b17f9c..87ba491 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.22 1997/11/18 15:07:35 phk Exp $
+ * $Id: union_subr.c,v 1.23 1997/12/27 02:56:26 bde Exp $
*/
#include <sys/param.h>
@@ -307,6 +307,7 @@ union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp, docache)
int hash;
int vflag;
int try;
+ int klocked;
if (uppervp == NULLVP && lowervp == NULLVP)
panic("union: unidentifiable allocation");
@@ -362,11 +363,27 @@ loop:
(un->un_uppervp == uppervp ||
un->un_uppervp == NULLVP) &&
(UNIONTOV(un)->v_mount == mp)) {
+ /*
+ * Do not assume that vget() does not
+ * lock the vnode even though flags
+ * argument is 0.
+ */
+ if ((un->un_uppervp != NULLVP) &&
+ ((un->un_flags & UN_KLOCK) == 0)) {
+ SETKLOCK(un);
+ klocked = 1;
+ } else {
+ klocked = 0;
+ }
if (vget(UNIONTOV(un), 0,
cnp ? cnp->cn_proc : NULL)) {
+ if (klocked)
+ CLEARKLOCK(un);
union_list_unlock(hash);
goto loop;
}
+ if (klocked)
+ CLEARKLOCK(un);
break;
}
}
diff --git a/sys/miscfs/union/union_vnops.c b/sys/miscfs/union/union_vnops.c
index 1c6b124..d856da2 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.47 1998/01/18 07:56:41 kato Exp $
+ * $Id: union_vnops.c,v 1.48 1998/01/18 08:17:48 kato Exp $
*/
#include <sys/param.h>
@@ -58,9 +58,6 @@
} \
}
-#define SETKLOCK(un) (un)->un_flags |= UN_KLOCK
-#define CLEARKLOCK(un) (un)->un_flags &= ~UN_KLOCK
-
static int union_abortop __P((struct vop_abortop_args *ap));
static int union_access __P((struct vop_access_args *ap));
static int union_advlock __P((struct vop_advlock_args *ap));
@@ -1548,11 +1545,13 @@ start:
un = VTOUNION(vp);
if (un->un_uppervp != NULLVP) {
- if (((un->un_flags & (UN_ULOCK | UN_KLOCK)) == 0) &&
+ if (((un->un_flags & UN_ULOCK) == 0) &&
(vp->v_usecount != 0)) {
- error = vn_lock(un->un_uppervp, flags, p);
- if (error)
- return (error);
+ if ((un->un_flags & UN_KLOCK) == 0) {
+ error = vn_lock(un->un_uppervp, flags, p);
+ if (error)
+ return (error);
+ }
un->un_flags |= UN_ULOCK;
}
}
@@ -1590,6 +1589,10 @@ 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 /* {
OpenPOWER on IntegriCloud