diff options
-rw-r--r-- | sys/fs/unionfs/union.h | 5 | ||||
-rw-r--r-- | sys/fs/unionfs/union_subr.c | 19 | ||||
-rw-r--r-- | sys/fs/unionfs/union_vnops.c | 19 | ||||
-rw-r--r-- | sys/miscfs/union/union.h | 5 | ||||
-rw-r--r-- | sys/miscfs/union/union_subr.c | 19 | ||||
-rw-r--r-- | sys/miscfs/union/union_vnops.c | 19 |
6 files changed, 66 insertions, 20 deletions
diff --git a/sys/fs/unionfs/union.h b/sys/fs/unionfs/union.h index 03e7033..f3bbb89 100644 --- a/sys/fs/unionfs/union.h +++ b/sys/fs/unionfs/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/fs/unionfs/union_subr.c b/sys/fs/unionfs/union_subr.c index 3b17f9c..87ba491 100644 --- a/sys/fs/unionfs/union_subr.c +++ b/sys/fs/unionfs/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/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c index 1c6b124..d856da2 100644 --- a/sys/fs/unionfs/union_vnops.c +++ b/sys/fs/unionfs/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 /* { 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 /* { |