Another update from JSP.
This commit is contained in:
parent
c0c42e4703
commit
ab119e2183
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)union.h 8.5 (Berkeley) 5/17/94
|
||||
* $Id: union.h,v 1.2 1994/06/15 23:07:58 mycroft Exp $
|
||||
* $Id: union.h,v 1.3 1994/06/17 15:21:33 mycroft Exp $
|
||||
*/
|
||||
|
||||
struct union_args {
|
||||
@ -75,6 +75,7 @@ struct union_node {
|
||||
struct vnode *un_uppervp; /* overlaying object */
|
||||
struct vnode *un_lowervp; /* underlying object */
|
||||
struct vnode *un_dirvp; /* Parent dir of uppervp */
|
||||
struct vnode *un_pvp; /* Parent vnode */
|
||||
char *un_path; /* saved component name */
|
||||
int un_hash; /* saved un_path hash value */
|
||||
int un_openl; /* # of opens on lowervp */
|
||||
|
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)union_subr.c 8.9 (Berkeley) 5/17/94
|
||||
* $Id: union_subr.c,v 1.2 1994/06/15 23:07:59 mycroft Exp $
|
||||
* $Id: union_subr.c,v 1.3 1994/06/17 15:21:35 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -131,8 +131,8 @@ union_updatevp(un, uppervp, lowervp)
|
||||
|
||||
if (ohash != nhash || !docache) {
|
||||
if (un->un_flags & UN_CACHED) {
|
||||
LIST_REMOVE(un, un_cache);
|
||||
un->un_flags &= ~UN_CACHED;
|
||||
LIST_REMOVE(un, un_cache);
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,7 +265,7 @@ int
|
||||
union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp)
|
||||
struct vnode **vpp;
|
||||
struct mount *mp;
|
||||
struct vnode *undvp;
|
||||
struct vnode *undvp; /* parent union vnode */
|
||||
struct vnode *dvp; /* may be null */
|
||||
struct componentname *cnp; /* may be null */
|
||||
struct vnode *uppervp; /* may be null */
|
||||
@ -470,6 +470,9 @@ loop:
|
||||
un->un_uppersz = VNOVAL;
|
||||
un->un_lowervp = lowervp;
|
||||
un->un_lowersz = VNOVAL;
|
||||
un->un_pvp = undvp;
|
||||
if (undvp != NULLVP)
|
||||
VREF(undvp);
|
||||
un->un_openl = 0;
|
||||
un->un_flags = UN_LOCKED;
|
||||
if (un->un_uppervp)
|
||||
@ -512,10 +515,12 @@ union_freevp(vp)
|
||||
struct union_node *un = VTOUNION(vp);
|
||||
|
||||
if (un->un_flags & UN_CACHED) {
|
||||
LIST_REMOVE(un, un_cache);
|
||||
un->un_flags &= ~UN_CACHED;
|
||||
LIST_REMOVE(un, un_cache);
|
||||
}
|
||||
|
||||
if (un->un_pvp != NULLVP)
|
||||
vrele(un->un_pvp);
|
||||
if (un->un_uppervp != NULLVP)
|
||||
vrele(un->un_uppervp);
|
||||
if (un->un_lowervp != NULLVP)
|
||||
@ -861,12 +866,16 @@ void
|
||||
union_removed_upper(un)
|
||||
struct union_node *un;
|
||||
{
|
||||
|
||||
if (un->un_flags & UN_ULOCK) {
|
||||
un->un_flags &= ~UN_ULOCK;
|
||||
VOP_UNLOCK(un->un_uppervp);
|
||||
}
|
||||
|
||||
union_newupper(un, NULLVP);
|
||||
if (un->un_flags & UN_CACHED) {
|
||||
un->un_flags &= ~UN_CACHED;
|
||||
LIST_REMOVE(un, un_cache);
|
||||
}
|
||||
}
|
||||
|
||||
struct vnode *
|
||||
|
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)union_vfsops.c 8.10 (Berkeley) 5/24/94
|
||||
* $Id: union_vfsops.c,v 1.2 1994/06/15 23:08:02 mycroft Exp $
|
||||
* $Id: union_vfsops.c,v 1.3 1994/06/17 15:21:37 mycroft Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -297,6 +297,7 @@ union_unmount(mp, mntflags, p)
|
||||
struct union_mount *um = MOUNTTOUNIONMOUNT(mp);
|
||||
struct vnode *um_rootvp;
|
||||
int error;
|
||||
int freeing;
|
||||
int flags = 0;
|
||||
extern int doforce;
|
||||
|
||||
@ -318,17 +319,48 @@ union_unmount(mp, mntflags, p)
|
||||
|
||||
if (error = union_root(mp, &um_rootvp))
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* Keep flushing vnodes from the mount list.
|
||||
* This is needed because of the un_pvp held
|
||||
* reference to the parent vnode.
|
||||
* If more vnodes have been freed on a given pass,
|
||||
* the try again. The loop will iterate at most
|
||||
* (d) times, where (d) is the maximum tree depth
|
||||
* in the filesystem.
|
||||
*/
|
||||
for (freeing = 0; vflush(mp, um_rootvp, flags) != 0;) {
|
||||
struct vnode *vp;
|
||||
int n;
|
||||
|
||||
/* count #vnodes held on mount list */
|
||||
for (n = 0, vp = mp->mnt_vnodelist.lh_first;
|
||||
vp != NULLVP;
|
||||
vp = vp->v_mntvnodes.le_next)
|
||||
n++;
|
||||
|
||||
/* if this is unchanged then stop */
|
||||
if (n == freeing)
|
||||
break;
|
||||
|
||||
/* otherwise try once more time */
|
||||
freeing = n;
|
||||
}
|
||||
|
||||
/* At this point the root vnode should have a single reference */
|
||||
if (um_rootvp->v_usecount > 1) {
|
||||
vput(um_rootvp);
|
||||
return (EBUSY);
|
||||
}
|
||||
#ifdef notneeded
|
||||
if (error = vflush(mp, um_rootvp, flags)) {
|
||||
vput(um_rootvp);
|
||||
return (error);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UNION_DIAGNOSTIC
|
||||
vprint("alias root of lower", um_rootvp);
|
||||
vprint("union root", um_rootvp);
|
||||
#endif
|
||||
/*
|
||||
* Discard references to upper and lower target vnodes.
|
||||
|
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)union_vnops.c 8.15 (Berkeley) 6/4/94
|
||||
* $Id: union_vnops.c,v 1.2 1994/06/15 23:08:04 mycroft Exp $
|
||||
* $Id: union_vnops.c,v 1.3 1994/06/17 15:21:39 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -241,6 +241,14 @@ union_lookup(ap)
|
||||
}
|
||||
} else {
|
||||
lerror = ENOENT;
|
||||
if ((cnp->cn_flags & ISDOTDOT) && dun->un_pvp != NULLVP) {
|
||||
lowervp = LOWERVP(dun->un_pvp);
|
||||
if (lowervp != NULLVP) {
|
||||
VREF(lowervp);
|
||||
VOP_LOCK(lowervp);
|
||||
lerror = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!lockparent)
|
||||
@ -597,7 +605,7 @@ union_getattr(ap)
|
||||
if ((vap != ap->a_vap) && (vap->va_type == VDIR))
|
||||
ap->a_vap->va_nlink += vap->va_nlink;
|
||||
|
||||
vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0];
|
||||
ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0];
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user