Simplify the handling of VCHR and VBLK vnodes using the new dev_t:

Make the alias list a SLIST.

        Drop the "fast recycling" optimization of vnodes (including
        the returning of a prexisting but stale vnode from checkalias).
        It doesn't buy us anything now that we don't hardlimit
        vnodes anymore.

        Rename checkalias2() and checkalias() to addalias() and
        addaliasu() - which takes dev_t and udev_t arg respectively.

        Make the revoke syscalls use vcount() instead of VALIASED.

        Remove VALIASED flag, we don't need it now and it is faster
        to traverse the much shorter lists than to maintain the
        flag.

        vfs_mountedon() can check the dev_t directly, all the vnodes
        point to the same one.

Print the devicename in specfs/vprint().

Remove a couple of stale LFS vnode flags.

Remove unimplemented/unused LK_DRAINED;
This commit is contained in:
Poul-Henning Kamp 1999-08-26 14:53:31 +00:00
parent 9c93810d2d
commit dbafb3660f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=50405
23 changed files with 160 additions and 630 deletions

View File

@ -28,7 +28,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
* $Id: svr4_fcntl.c,v 1.3 1999/07/30 12:45:15 newton Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
@ -280,7 +280,7 @@ fd_revoke(p, fd)
(error = suser(p)) != 0)
goto out;
if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
if (vcount(vp) > 1)
VOP_REVOKE(vp, REVOKEALL);
out:
vrele(vp);

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)cd9660_vfsops.c 8.18 (Berkeley) 5/22/95
* $Id: cd9660_vfsops.c,v 1.59 1999/08/23 21:07:12 bde Exp $
* $Id: cd9660_vfsops.c,v 1.60 1999/08/25 12:24:39 phk Exp $
*/
#include <sys/param.h>
@ -892,23 +892,7 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
* if device, look at device number table for translation
*/
vp->v_op = cd9660_specop_p;
if ((nvp = checkalias(vp, ip->inode.iso_rdev, mp)) != NULL) {
/*
* Discard unneeded vnode, but save its iso_node.
* Note that the lock is carried over in the iso_node
* to the replacement vnode.
*/
nvp->v_data = vp->v_data;
vp->v_data = NULL;
vp->v_op = spec_vnodeop_p;
vrele(vp);
vgone(vp);
/*
* Reinitialize aliased inode.
*/
vp = nvp;
ip->i_vnode = vp;
}
addaliasu(vp, ip->inode.iso_rdev);
break;
default:
break;

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)spec_vnops.c 8.14 (Berkeley) 5/21/95
* $Id: spec_vnops.c,v 1.97 1999/08/17 04:02:04 alc Exp $
* $Id: spec_vnops.c,v 1.98 1999/08/25 00:26:34 julian Exp $
*/
#include <sys/param.h>
@ -686,8 +686,7 @@ spec_print(ap)
} */ *ap;
{
printf("tag VT_NON, dev %d, %d\n", major(ap->a_vp->v_rdev),
minor(ap->a_vp->v_rdev));
printf("tag VT_NON, dev %s\n", devtoname(ap->a_vp->v_rdev));
return (0);
}

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)cd9660_vfsops.c 8.18 (Berkeley) 5/22/95
* $Id: cd9660_vfsops.c,v 1.59 1999/08/23 21:07:12 bde Exp $
* $Id: cd9660_vfsops.c,v 1.60 1999/08/25 12:24:39 phk Exp $
*/
#include <sys/param.h>
@ -892,23 +892,7 @@ cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
* if device, look at device number table for translation
*/
vp->v_op = cd9660_specop_p;
if ((nvp = checkalias(vp, ip->inode.iso_rdev, mp)) != NULL) {
/*
* Discard unneeded vnode, but save its iso_node.
* Note that the lock is carried over in the iso_node
* to the replacement vnode.
*/
nvp->v_data = vp->v_data;
vp->v_data = NULL;
vp->v_op = spec_vnodeop_p;
vrele(vp);
vgone(vp);
/*
* Reinitialize aliased inode.
*/
vp = nvp;
ip->i_vnode = vp;
}
addaliasu(vp, ip->inode.iso_rdev);
break;
default:
break;

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
* $Id: vfs_subr.c,v 1.219 1999/08/25 04:55:17 julian Exp $
* $Id: vfs_subr.c,v 1.220 1999/08/25 12:24:34 phk Exp $
*/
/*
@ -1278,119 +1278,48 @@ bdevvp(dev, vpp)
return (error);
}
vp = nvp;
/* dev2udev() results in a CDEV, so we need to cheat here. */
vp->v_type = VBLK;
if ((nvp = checkalias2(vp, dev, (struct mount *)0)) != NULL) {
vput(vp);
vp = nvp;
}
addalias(vp, dev);
*vpp = vp;
return (0);
}
/*
* Check to see if the new vnode represents a special device
* for which we already have a vnode (either because of
* bdevvp() or because of a different vnode representing
* the same block device). If such an alias exists, deallocate
* the existing contents and return the aliased vnode. The
* caller is responsible for filling it with its new contents.
* Add vnode to the alias list hung off the dev_t.
*
* The reason for this gunk is that multiple vnodes can reference
* the same physical device, so checking vp->v_usecount to see
* how many users there are is inadequate; the v_usecount for
* the vnodes need to be accumulated. vcount() does that.
*/
struct vnode *
checkalias(nvp, nvp_rdev, mp)
register struct vnode *nvp;
void
addaliasu(nvp, nvp_rdev)
struct vnode *nvp;
udev_t nvp_rdev;
struct mount *mp;
{
dev_t dev;
if (nvp->v_type != VBLK && nvp->v_type != VCHR)
return (NULLVP);
panic("addaliasu on non-special vnode");
dev = udev2dev(nvp_rdev, nvp->v_type == VBLK ? 1 : 0);
return (checkalias2(nvp, dev, mp));
nvp->v_rdev = udev2dev(nvp_rdev, nvp->v_type == VBLK ? 1 : 0);
simple_lock(&spechash_slock);
SLIST_INSERT_HEAD(&nvp->v_rdev->si_hlist, nvp, v_specnext);
simple_unlock(&spechash_slock);
}
struct vnode *
checkalias2(nvp, dev, mp)
register struct vnode *nvp;
void
addalias(nvp, dev)
struct vnode *nvp;
dev_t dev;
struct mount *mp;
{
struct proc *p = curproc; /* XXX */
struct vnode *vp;
struct vnode **vpp;
if (nvp->v_type != VBLK && nvp->v_type != VCHR)
return (NULLVP);
vpp = &dev->si_hlist;
loop:
panic("addalias on non-special vnode");
nvp->v_rdev = dev;
simple_lock(&spechash_slock);
for (vp = *vpp; vp; vp = vp->v_specnext) {
if (nvp->v_type != vp->v_type)
continue;
/*
* Alias, but not in use, so flush it out.
* Only alias active device nodes.
* Not sure why we don't re-use this like we do below.
*/
simple_lock(&vp->v_interlock);
if (vp->v_usecount == 0) {
simple_unlock(&spechash_slock);
vgonel(vp, p);
goto loop;
}
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p)) {
/*
* It dissappeared, and we may have slept.
* Restart from the beginning
*/
simple_unlock(&spechash_slock);
goto loop;
}
break;
}
/*
* It would be a lot clearer what is going on here if
* this had been expressed as:
* if ( vp && (vp->v_tag == VT_NULL))
* and the clauses had been swapped.
*/
if (vp == NULL || vp->v_tag != VT_NON) {
struct specinfo *sinfo;
/*
* Put the new vnode into the hash chain.
* and if there was an alias, connect them.
*/
nvp->v_specnext = *vpp;
*vpp = nvp;
nvp->v_rdev = sinfo = dev;
simple_unlock(&spechash_slock);
if (vp != NULLVP) {
nvp->v_flag |= VALIASED;
vp->v_flag |= VALIASED;
vput(vp);
}
return (NULLVP);
}
/*
* if ( vp && (vp->v_tag == VT_NULL))
* We have a vnode alias, but it is a trashed.
* Make it look like it's newly allocated. (by getnewvnode())
* The caller should use this instead.
*/
SLIST_INSERT_HEAD(&dev->si_hlist, nvp, v_specnext);
simple_unlock(&spechash_slock);
VOP_UNLOCK(vp, 0, p);
simple_lock(&vp->v_interlock);
vclean(vp, 0, p);
vp->v_op = nvp->v_op;
vp->v_tag = nvp->v_tag;
nvp->v_type = VNON;
insmntque(vp, mp);
return (vp);
}
/*
@ -1757,12 +1686,6 @@ vclean(vp, flags, p)
cache_purge(vp);
if (vp->v_vnlock) {
#if 0 /* This is the only place we have LK_DRAINED in the entire kernel ??? */
#ifdef DIAGNOSTIC
if ((vp->v_vnlock->lk_flags & LK_DRAINED) == 0)
vprint("vclean: lock not drained", vp);
#endif
#endif
FREE(vp->v_vnlock, M_VNODE);
vp->v_vnlock = NULL;
}
@ -1795,56 +1718,30 @@ vop_revoke(ap)
} */ *ap;
{
struct vnode *vp, *vq;
struct proc *p = curproc; /* XXX */
dev_t dev;
KASSERT((ap->a_flags & REVOKEALL) != 0, ("vop_revoke"));
vp = ap->a_vp;
simple_lock(&vp->v_interlock);
if (vp->v_flag & VALIASED) {
/*
* If a vgone (or vclean) is already in progress,
* wait until it is done and return.
*/
if (vp->v_flag & VXLOCK) {
vp->v_flag |= VXWANT;
simple_unlock(&vp->v_interlock);
tsleep((caddr_t)vp, PINOD, "vop_revokeall", 0);
return (0);
}
/*
* Ensure that vp will not be vgone'd while we
* are eliminating its aliases.
*/
vp->v_flag |= VXLOCK;
/*
* If a vgone (or vclean) is already in progress,
* wait until it is done and return.
*/
if (vp->v_flag & VXLOCK) {
vp->v_flag |= VXWANT;
simple_unlock(&vp->v_interlock);
while (vp->v_flag & VALIASED) {
simple_lock(&spechash_slock);
for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
if (vq->v_type != vp->v_type || vp == vq)
continue;
simple_unlock(&spechash_slock);
vgone(vq);
break;
}
if (vq == NULLVP) {
simple_unlock(&spechash_slock);
}
}
/*
* Remove the lock so that vgone below will
* really eliminate the vnode after which time
* vgone will awaken any sleepers.
*/
simple_lock(&vp->v_interlock);
vp->v_flag &= ~VXLOCK;
if (vp->v_flag & VXWANT) {
vp->v_flag &= ~VXWANT;
wakeup(vp);
}
tsleep((caddr_t)vp, PINOD, "vop_revokeall", 0);
return (0);
}
dev = vp->v_rdev;
for (;;) {
simple_lock(&spechash_slock);
vq = SLIST_FIRST(&dev->si_hlist);
simple_unlock(&spechash_slock);
if (!vq)
break;
vgone(vq);
}
vgonel(vp, p);
return (0);
}
@ -1894,8 +1791,6 @@ vgonel(vp, p)
struct proc *p;
{
int s;
struct vnode *vq;
struct vnode *vx;
/*
* If a vgone (or vclean) is already in progress,
@ -1923,35 +1818,9 @@ vgonel(vp, p)
* If special device, remove it from special device alias list
* if it is on one.
*/
if ((vp->v_type == VBLK || vp->v_type == VCHR) && vp->v_rdev != 0) {
if ((vp->v_type == VBLK || vp->v_type == VCHR) && vp->v_rdev != NULL) {
simple_lock(&spechash_slock);
if (vp->v_hashchain == vp) {
vp->v_hashchain = vp->v_specnext;
} else {
for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
if (vq->v_specnext != vp)
continue;
vq->v_specnext = vp->v_specnext;
break;
}
if (vq == NULL)
panic("missing bdev");
}
if (vp->v_flag & VALIASED) {
vx = NULL;
for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
if (vq->v_type != vp->v_type)
continue;
if (vx)
break;
vx = vq;
}
if (vx == NULL)
panic("missing alias");
if (vq == NULL)
vx->v_flag &= ~VALIASED;
vp->v_flag &= ~VALIASED;
}
SLIST_REMOVE(&vp->v_hashchain, vp, vnode, v_specnext);
simple_unlock(&spechash_slock);
vp->v_rdev = NULL;
}
@ -1996,19 +1865,18 @@ vfinddev(dev, type, vpp)
enum vtype type;
struct vnode **vpp;
{
register struct vnode *vp;
int rc = 0;
struct vnode *vp;
simple_lock(&spechash_slock);
for (vp = dev->si_hlist; vp; vp = vp->v_specnext) {
if (type != vp->v_type)
continue;
*vpp = vp;
rc = 1;
break;
SLIST_FOREACH(vp, &dev->si_hlist, v_specnext) {
if (type == vp->v_type) {
*vpp = vp;
simple_unlock(&spechash_slock);
return (1);
}
}
simple_unlock(&spechash_slock);
return (rc);
return (0);
}
/*
@ -2016,32 +1884,19 @@ vfinddev(dev, type, vpp)
*/
int
vcount(vp)
register struct vnode *vp;
struct vnode *vp;
{
struct vnode *vq, *vnext;
int count;
loop:
if ((vp->v_flag & VALIASED) == 0)
return (vp->v_usecount);
count = 0;
simple_lock(&spechash_slock);
for (count = 0, vq = vp->v_hashchain; vq; vq = vnext) {
vnext = vq->v_specnext;
if (vq->v_type != vp->v_type)
continue;
/*
* Alias, but not in use, so flush it out.
*/
if (vq->v_usecount == 0 && vq != vp) {
simple_unlock(&spechash_slock);
vgone(vq);
goto loop;
}
SLIST_FOREACH(vq, &vp->v_hashchain, v_specnext)
count += vq->v_usecount;
}
simple_unlock(&spechash_slock);
return (count);
}
/*
* Print out a description of a vnode.
*/
@ -2051,7 +1906,7 @@ static char *typename[] =
void
vprint(label, vp)
char *label;
register struct vnode *vp;
struct vnode *vp;
{
char buf[96];
@ -2075,8 +1930,6 @@ vprint(label, vp)
strcat(buf, "|VXWANT");
if (vp->v_flag & VBWAIT)
strcat(buf, "|VBWAIT");
if (vp->v_flag & VALIASED)
strcat(buf, "|VALIASED");
if (vp->v_flag & VDOOMED)
strcat(buf, "|VDOOMED");
if (vp->v_flag & VFREE)
@ -2281,24 +2134,10 @@ int
vfs_mountedon(vp)
struct vnode *vp;
{
struct vnode *vq;
int error = 0;
if (vp->v_specmountpoint != NULL)
return (EBUSY);
if (vp->v_flag & VALIASED) {
simple_lock(&spechash_slock);
for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
if (vq->v_type != vp->v_type)
continue;
if (vq->v_specmountpoint != NULL) {
error = EBUSY;
break;
}
}
simple_unlock(&spechash_slock);
}
return (error);
return (0);
}
/*

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
* $Id: vfs_syscalls.c,v 1.131 1999/08/22 01:46:57 jdp Exp $
* $Id: vfs_syscalls.c,v 1.132 1999/08/22 16:50:30 jdp Exp $
*/
/* For 4.3 integer FS ID compatibility */
@ -3010,7 +3010,7 @@ revoke(p, uap)
if (p->p_ucred->cr_uid != vattr.va_uid &&
(error = suser_xxx(0, p, PRISON_ROOT)))
goto out;
if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
if (vcount(vp) > 1)
VOP_REVOKE(vp, REVOKEALL);
out:
vrele(vp);

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
* $Id: vfs_subr.c,v 1.219 1999/08/25 04:55:17 julian Exp $
* $Id: vfs_subr.c,v 1.220 1999/08/25 12:24:34 phk Exp $
*/
/*
@ -1278,119 +1278,48 @@ bdevvp(dev, vpp)
return (error);
}
vp = nvp;
/* dev2udev() results in a CDEV, so we need to cheat here. */
vp->v_type = VBLK;
if ((nvp = checkalias2(vp, dev, (struct mount *)0)) != NULL) {
vput(vp);
vp = nvp;
}
addalias(vp, dev);
*vpp = vp;
return (0);
}
/*
* Check to see if the new vnode represents a special device
* for which we already have a vnode (either because of
* bdevvp() or because of a different vnode representing
* the same block device). If such an alias exists, deallocate
* the existing contents and return the aliased vnode. The
* caller is responsible for filling it with its new contents.
* Add vnode to the alias list hung off the dev_t.
*
* The reason for this gunk is that multiple vnodes can reference
* the same physical device, so checking vp->v_usecount to see
* how many users there are is inadequate; the v_usecount for
* the vnodes need to be accumulated. vcount() does that.
*/
struct vnode *
checkalias(nvp, nvp_rdev, mp)
register struct vnode *nvp;
void
addaliasu(nvp, nvp_rdev)
struct vnode *nvp;
udev_t nvp_rdev;
struct mount *mp;
{
dev_t dev;
if (nvp->v_type != VBLK && nvp->v_type != VCHR)
return (NULLVP);
panic("addaliasu on non-special vnode");
dev = udev2dev(nvp_rdev, nvp->v_type == VBLK ? 1 : 0);
return (checkalias2(nvp, dev, mp));
nvp->v_rdev = udev2dev(nvp_rdev, nvp->v_type == VBLK ? 1 : 0);
simple_lock(&spechash_slock);
SLIST_INSERT_HEAD(&nvp->v_rdev->si_hlist, nvp, v_specnext);
simple_unlock(&spechash_slock);
}
struct vnode *
checkalias2(nvp, dev, mp)
register struct vnode *nvp;
void
addalias(nvp, dev)
struct vnode *nvp;
dev_t dev;
struct mount *mp;
{
struct proc *p = curproc; /* XXX */
struct vnode *vp;
struct vnode **vpp;
if (nvp->v_type != VBLK && nvp->v_type != VCHR)
return (NULLVP);
vpp = &dev->si_hlist;
loop:
panic("addalias on non-special vnode");
nvp->v_rdev = dev;
simple_lock(&spechash_slock);
for (vp = *vpp; vp; vp = vp->v_specnext) {
if (nvp->v_type != vp->v_type)
continue;
/*
* Alias, but not in use, so flush it out.
* Only alias active device nodes.
* Not sure why we don't re-use this like we do below.
*/
simple_lock(&vp->v_interlock);
if (vp->v_usecount == 0) {
simple_unlock(&spechash_slock);
vgonel(vp, p);
goto loop;
}
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p)) {
/*
* It dissappeared, and we may have slept.
* Restart from the beginning
*/
simple_unlock(&spechash_slock);
goto loop;
}
break;
}
/*
* It would be a lot clearer what is going on here if
* this had been expressed as:
* if ( vp && (vp->v_tag == VT_NULL))
* and the clauses had been swapped.
*/
if (vp == NULL || vp->v_tag != VT_NON) {
struct specinfo *sinfo;
/*
* Put the new vnode into the hash chain.
* and if there was an alias, connect them.
*/
nvp->v_specnext = *vpp;
*vpp = nvp;
nvp->v_rdev = sinfo = dev;
simple_unlock(&spechash_slock);
if (vp != NULLVP) {
nvp->v_flag |= VALIASED;
vp->v_flag |= VALIASED;
vput(vp);
}
return (NULLVP);
}
/*
* if ( vp && (vp->v_tag == VT_NULL))
* We have a vnode alias, but it is a trashed.
* Make it look like it's newly allocated. (by getnewvnode())
* The caller should use this instead.
*/
SLIST_INSERT_HEAD(&dev->si_hlist, nvp, v_specnext);
simple_unlock(&spechash_slock);
VOP_UNLOCK(vp, 0, p);
simple_lock(&vp->v_interlock);
vclean(vp, 0, p);
vp->v_op = nvp->v_op;
vp->v_tag = nvp->v_tag;
nvp->v_type = VNON;
insmntque(vp, mp);
return (vp);
}
/*
@ -1757,12 +1686,6 @@ vclean(vp, flags, p)
cache_purge(vp);
if (vp->v_vnlock) {
#if 0 /* This is the only place we have LK_DRAINED in the entire kernel ??? */
#ifdef DIAGNOSTIC
if ((vp->v_vnlock->lk_flags & LK_DRAINED) == 0)
vprint("vclean: lock not drained", vp);
#endif
#endif
FREE(vp->v_vnlock, M_VNODE);
vp->v_vnlock = NULL;
}
@ -1795,56 +1718,30 @@ vop_revoke(ap)
} */ *ap;
{
struct vnode *vp, *vq;
struct proc *p = curproc; /* XXX */
dev_t dev;
KASSERT((ap->a_flags & REVOKEALL) != 0, ("vop_revoke"));
vp = ap->a_vp;
simple_lock(&vp->v_interlock);
if (vp->v_flag & VALIASED) {
/*
* If a vgone (or vclean) is already in progress,
* wait until it is done and return.
*/
if (vp->v_flag & VXLOCK) {
vp->v_flag |= VXWANT;
simple_unlock(&vp->v_interlock);
tsleep((caddr_t)vp, PINOD, "vop_revokeall", 0);
return (0);
}
/*
* Ensure that vp will not be vgone'd while we
* are eliminating its aliases.
*/
vp->v_flag |= VXLOCK;
/*
* If a vgone (or vclean) is already in progress,
* wait until it is done and return.
*/
if (vp->v_flag & VXLOCK) {
vp->v_flag |= VXWANT;
simple_unlock(&vp->v_interlock);
while (vp->v_flag & VALIASED) {
simple_lock(&spechash_slock);
for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
if (vq->v_type != vp->v_type || vp == vq)
continue;
simple_unlock(&spechash_slock);
vgone(vq);
break;
}
if (vq == NULLVP) {
simple_unlock(&spechash_slock);
}
}
/*
* Remove the lock so that vgone below will
* really eliminate the vnode after which time
* vgone will awaken any sleepers.
*/
simple_lock(&vp->v_interlock);
vp->v_flag &= ~VXLOCK;
if (vp->v_flag & VXWANT) {
vp->v_flag &= ~VXWANT;
wakeup(vp);
}
tsleep((caddr_t)vp, PINOD, "vop_revokeall", 0);
return (0);
}
dev = vp->v_rdev;
for (;;) {
simple_lock(&spechash_slock);
vq = SLIST_FIRST(&dev->si_hlist);
simple_unlock(&spechash_slock);
if (!vq)
break;
vgone(vq);
}
vgonel(vp, p);
return (0);
}
@ -1894,8 +1791,6 @@ vgonel(vp, p)
struct proc *p;
{
int s;
struct vnode *vq;
struct vnode *vx;
/*
* If a vgone (or vclean) is already in progress,
@ -1923,35 +1818,9 @@ vgonel(vp, p)
* If special device, remove it from special device alias list
* if it is on one.
*/
if ((vp->v_type == VBLK || vp->v_type == VCHR) && vp->v_rdev != 0) {
if ((vp->v_type == VBLK || vp->v_type == VCHR) && vp->v_rdev != NULL) {
simple_lock(&spechash_slock);
if (vp->v_hashchain == vp) {
vp->v_hashchain = vp->v_specnext;
} else {
for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
if (vq->v_specnext != vp)
continue;
vq->v_specnext = vp->v_specnext;
break;
}
if (vq == NULL)
panic("missing bdev");
}
if (vp->v_flag & VALIASED) {
vx = NULL;
for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
if (vq->v_type != vp->v_type)
continue;
if (vx)
break;
vx = vq;
}
if (vx == NULL)
panic("missing alias");
if (vq == NULL)
vx->v_flag &= ~VALIASED;
vp->v_flag &= ~VALIASED;
}
SLIST_REMOVE(&vp->v_hashchain, vp, vnode, v_specnext);
simple_unlock(&spechash_slock);
vp->v_rdev = NULL;
}
@ -1996,19 +1865,18 @@ vfinddev(dev, type, vpp)
enum vtype type;
struct vnode **vpp;
{
register struct vnode *vp;
int rc = 0;
struct vnode *vp;
simple_lock(&spechash_slock);
for (vp = dev->si_hlist; vp; vp = vp->v_specnext) {
if (type != vp->v_type)
continue;
*vpp = vp;
rc = 1;
break;
SLIST_FOREACH(vp, &dev->si_hlist, v_specnext) {
if (type == vp->v_type) {
*vpp = vp;
simple_unlock(&spechash_slock);
return (1);
}
}
simple_unlock(&spechash_slock);
return (rc);
return (0);
}
/*
@ -2016,32 +1884,19 @@ vfinddev(dev, type, vpp)
*/
int
vcount(vp)
register struct vnode *vp;
struct vnode *vp;
{
struct vnode *vq, *vnext;
int count;
loop:
if ((vp->v_flag & VALIASED) == 0)
return (vp->v_usecount);
count = 0;
simple_lock(&spechash_slock);
for (count = 0, vq = vp->v_hashchain; vq; vq = vnext) {
vnext = vq->v_specnext;
if (vq->v_type != vp->v_type)
continue;
/*
* Alias, but not in use, so flush it out.
*/
if (vq->v_usecount == 0 && vq != vp) {
simple_unlock(&spechash_slock);
vgone(vq);
goto loop;
}
SLIST_FOREACH(vq, &vp->v_hashchain, v_specnext)
count += vq->v_usecount;
}
simple_unlock(&spechash_slock);
return (count);
}
/*
* Print out a description of a vnode.
*/
@ -2051,7 +1906,7 @@ static char *typename[] =
void
vprint(label, vp)
char *label;
register struct vnode *vp;
struct vnode *vp;
{
char buf[96];
@ -2075,8 +1930,6 @@ vprint(label, vp)
strcat(buf, "|VXWANT");
if (vp->v_flag & VBWAIT)
strcat(buf, "|VBWAIT");
if (vp->v_flag & VALIASED)
strcat(buf, "|VALIASED");
if (vp->v_flag & VDOOMED)
strcat(buf, "|VDOOMED");
if (vp->v_flag & VFREE)
@ -2281,24 +2134,10 @@ int
vfs_mountedon(vp)
struct vnode *vp;
{
struct vnode *vq;
int error = 0;
if (vp->v_specmountpoint != NULL)
return (EBUSY);
if (vp->v_flag & VALIASED) {
simple_lock(&spechash_slock);
for (vq = vp->v_hashchain; vq; vq = vq->v_specnext) {
if (vq->v_type != vp->v_type)
continue;
if (vq->v_specmountpoint != NULL) {
error = EBUSY;
break;
}
}
simple_unlock(&spechash_slock);
}
return (error);
return (0);
}
/*

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
* $Id: vfs_syscalls.c,v 1.131 1999/08/22 01:46:57 jdp Exp $
* $Id: vfs_syscalls.c,v 1.132 1999/08/22 16:50:30 jdp Exp $
*/
/* For 4.3 integer FS ID compatibility */
@ -3010,7 +3010,7 @@ revoke(p, uap)
if (p->p_ucred->cr_uid != vattr.va_uid &&
(error = suser_xxx(0, p, PRISON_ROOT)))
goto out;
if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
if (vcount(vp) > 1)
VOP_REVOKE(vp, REVOKEALL);
out:
vrele(vp);

View File

@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: devfs_tree.c,v 1.61 1999/08/25 04:55:18 julian Exp $
* $Id: devfs_tree.c,v 1.62 1999/08/25 22:50:11 julian Exp $
*/
@ -982,23 +982,11 @@ DBPRINT(("(New vnode)"));
break;
case DEV_BDEV:
vn_p->v_type = VBLK;
if ((nvp = checkalias2(vn_p,
dnp->by.dev.dev,
(struct mount *)0)) != NULL)
{
vput(vn_p);
vn_p = nvp;
}
addalias(vn_p, dnp->by.dev.dev);
break;
case DEV_CDEV:
vn_p->v_type = VCHR;
if ((nvp = checkalias2(vn_p,
dnp->by.dev.dev,
(struct mount *)0)) != NULL)
{
vput(vn_p);
vn_p = nvp;
}
addalias(vn_p, dnp->by.dev.dev);
break;
case DEV_DDEV:
break;

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)spec_vnops.c 8.14 (Berkeley) 5/21/95
* $Id: spec_vnops.c,v 1.97 1999/08/17 04:02:04 alc Exp $
* $Id: spec_vnops.c,v 1.98 1999/08/25 00:26:34 julian Exp $
*/
#include <sys/param.h>
@ -686,8 +686,7 @@ spec_print(ap)
} */ *ap;
{
printf("tag VT_NON, dev %d, %d\n", major(ap->a_vp->v_rdev),
minor(ap->a_vp->v_rdev));
printf("tag VT_NON, dev %s\n", devtoname(ap->a_vp->v_rdev));
return (0);
}

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95
* $Id: nfs_subs.c,v 1.79 1999/07/17 18:43:47 phk Exp $
* $Id: nfs_subs.c,v 1.80 1999/08/08 18:42:55 phk Exp $
*/
/*
@ -1311,26 +1311,7 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
}
if (vp->v_type == VCHR || vp->v_type == VBLK) {
vp->v_op = spec_nfsv2nodeop_p;
nvp = checkalias(vp, rdev, vp->v_mount);
if (nvp) {
/*
* Discard unneeded vnode, but save its nfsnode.
* Since the nfsnode does not have a lock, its
* vnode lock has to be carried over.
*/
nvp->v_vnlock = vp->v_vnlock;
vp->v_vnlock = NULL;
nvp->v_data = vp->v_data;
vp->v_data = NULL;
vp->v_op = spec_vnodeop_p;
vrele(vp);
vgone(vp);
/*
* Reinitialize aliased node.
*/
np->n_vnode = nvp;
*vpp = vp = nvp;
}
addaliasu(vp, rdev);
}
np->n_mtime = mtime.tv_sec;
}

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95
* $Id: nfs_subs.c,v 1.79 1999/07/17 18:43:47 phk Exp $
* $Id: nfs_subs.c,v 1.80 1999/08/08 18:42:55 phk Exp $
*/
/*
@ -1311,26 +1311,7 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
}
if (vp->v_type == VCHR || vp->v_type == VBLK) {
vp->v_op = spec_nfsv2nodeop_p;
nvp = checkalias(vp, rdev, vp->v_mount);
if (nvp) {
/*
* Discard unneeded vnode, but save its nfsnode.
* Since the nfsnode does not have a lock, its
* vnode lock has to be carried over.
*/
nvp->v_vnlock = vp->v_vnlock;
vp->v_vnlock = NULL;
nvp->v_data = vp->v_data;
vp->v_data = NULL;
vp->v_op = spec_vnodeop_p;
vrele(vp);
vgone(vp);
/*
* Reinitialize aliased node.
*/
np->n_vnode = nvp;
*vpp = vp = nvp;
}
addaliasu(vp, rdev);
}
np->n_mtime = mtime.tv_sec;
}

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95
* $Id: nfs_subs.c,v 1.79 1999/07/17 18:43:47 phk Exp $
* $Id: nfs_subs.c,v 1.80 1999/08/08 18:42:55 phk Exp $
*/
/*
@ -1311,26 +1311,7 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
}
if (vp->v_type == VCHR || vp->v_type == VBLK) {
vp->v_op = spec_nfsv2nodeop_p;
nvp = checkalias(vp, rdev, vp->v_mount);
if (nvp) {
/*
* Discard unneeded vnode, but save its nfsnode.
* Since the nfsnode does not have a lock, its
* vnode lock has to be carried over.
*/
nvp->v_vnlock = vp->v_vnlock;
vp->v_vnlock = NULL;
nvp->v_data = vp->v_data;
vp->v_data = NULL;
vp->v_op = spec_vnodeop_p;
vrele(vp);
vgone(vp);
/*
* Reinitialize aliased node.
*/
np->n_vnode = nvp;
*vpp = vp = nvp;
}
addaliasu(vp, rdev);
}
np->n_mtime = mtime.tv_sec;
}

View File

@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95
* $Id: nfs_subs.c,v 1.79 1999/07/17 18:43:47 phk Exp $
* $Id: nfs_subs.c,v 1.80 1999/08/08 18:42:55 phk Exp $
*/
/*
@ -1311,26 +1311,7 @@ nfs_loadattrcache(vpp, mdp, dposp, vaper)
}
if (vp->v_type == VCHR || vp->v_type == VBLK) {
vp->v_op = spec_nfsv2nodeop_p;
nvp = checkalias(vp, rdev, vp->v_mount);
if (nvp) {
/*
* Discard unneeded vnode, but save its nfsnode.
* Since the nfsnode does not have a lock, its
* vnode lock has to be carried over.
*/
nvp->v_vnlock = vp->v_vnlock;
vp->v_vnlock = NULL;
nvp->v_data = vp->v_data;
vp->v_data = NULL;
vp->v_op = spec_vnodeop_p;
vrele(vp);
vgone(vp);
/*
* Reinitialize aliased node.
*/
np->n_vnode = nvp;
*vpp = vp = nvp;
}
addaliasu(vp, rdev);
}
np->n_mtime = mtime.tv_sec;
}

View File

@ -28,7 +28,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
* $Id: svr4_fcntl.c,v 1.3 1999/07/30 12:45:15 newton Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
@ -280,7 +280,7 @@ fd_revoke(p, fd)
(error = suser(p)) != 0)
goto out;
if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
if (vcount(vp) > 1)
VOP_REVOKE(vp, REVOKEALL);
out:
vrele(vp);

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)conf.h 8.5 (Berkeley) 1/9/95
* $Id: conf.h,v 1.77 1999/08/23 20:59:17 phk Exp $
* $Id: conf.h,v 1.78 1999/08/25 22:50:12 julian Exp $
*/
#ifndef _SYS_CONF_H_
@ -53,7 +53,7 @@ struct specinfo {
udev_t si_udev;
SLIST_ENTRY(specinfo) si_hash;
struct vnode *si_hlist;
SLIST_HEAD(, vnode) si_hlist;
char si_name[SPECNAMELEN + 1];
void *si_drv1, *si_drv2;
struct cdevsw *si_devsw;

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)conf.h 8.5 (Berkeley) 1/9/95
* $Id: conf.h,v 1.77 1999/08/23 20:59:17 phk Exp $
* $Id: conf.h,v 1.78 1999/08/25 22:50:12 julian Exp $
*/
#ifndef _SYS_CONF_H_
@ -53,7 +53,7 @@ struct specinfo {
udev_t si_udev;
SLIST_ENTRY(specinfo) si_hash;
struct vnode *si_hlist;
SLIST_HEAD(, vnode) si_hlist;
char si_name[SPECNAMELEN + 1];
void *si_drv1, *si_drv2;
struct cdevsw *si_devsw;

View File

@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* @(#)lock.h 8.12 (Berkeley) 5/19/95
* $Id: lock.h,v 1.13 1999/01/20 14:49:12 eivind Exp $
* $Id: lock.h,v 1.14 1999/06/26 02:45:40 mckusick Exp $
*/
#ifndef _LOCK_H_
@ -129,7 +129,6 @@ struct lock {
#define LK_HAVE_EXCL 0x00000400 /* exclusive lock obtained */
#define LK_WAITDRAIN 0x00000800 /* process waiting for lock to drain */
#define LK_DRAINING 0x00004000 /* lock is being drained */
#define LK_DRAINED 0x00008000 /* lock has been decommissioned */
/*
* Control flags
*

View File

@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* @(#)lock.h 8.12 (Berkeley) 5/19/95
* $Id: lock.h,v 1.13 1999/01/20 14:49:12 eivind Exp $
* $Id: lock.h,v 1.14 1999/06/26 02:45:40 mckusick Exp $
*/
#ifndef _LOCK_H_
@ -129,7 +129,6 @@ struct lock {
#define LK_HAVE_EXCL 0x00000400 /* exclusive lock obtained */
#define LK_WAITDRAIN 0x00000800 /* process waiting for lock to drain */
#define LK_DRAINING 0x00004000 /* lock is being drained */
#define LK_DRAINED 0x00008000 /* lock has been decommissioned */
/*
* Control flags
*

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)vnode.h 8.7 (Berkeley) 2/4/94
* $Id: vnode.h,v 1.96 1999/08/25 04:55:20 julian Exp $
* $Id: vnode.h,v 1.97 1999/08/25 12:24:30 phk Exp $
*/
#ifndef _SYS_VNODE_H_
@ -103,7 +103,7 @@ struct vnode {
struct socket *vu_socket; /* unix ipc (VSOCK) */
struct {
struct specinfo *vu_specinfo; /* device (VCHR, VBLK) */
struct vnode *vu_specnext;
SLIST_ENTRY(vnode) vu_specnext;
} vu_spec;
struct fifoinfo *vu_fifoinfo; /* fifo (VFIFO) */
} v_un;
@ -155,10 +155,10 @@ struct vnode {
#define VXLOCK 0x00100 /* vnode is locked to change underlying type */
#define VXWANT 0x00200 /* process is waiting for vnode */
#define VBWAIT 0x00400 /* waiting for output to complete */
#define VALIASED 0x00800 /* vnode has an alias */
#define VDIROP 0x01000 /* LFS: vnode is involved in a directory op */
/* open for business 0x00800 */
/* open for business 0x01000 */
#define VOBJBUF 0x02000 /* Allocate buffers in VM object */
#define VNINACT 0x04000 /* LFS: skip ufs_inactive() in lfs_vunref */
/* open for business 0x04000 */
#define VAGE 0x08000 /* Insert vnode at head of free list */
#define VOLOCK 0x10000 /* vnode is locked waiting for an object */
#define VOWANT 0x20000 /* a process is waiting for VOLOCK */
@ -491,6 +491,8 @@ struct vop_bwrite_args;
extern int (*lease_check_hook) __P((struct vop_lease_args *));
void addalias __P((struct vnode *vp, dev_t nvp_rdev));
void addaliasu __P((struct vnode *vp, udev_t nvp_rdev));
int bdevvp __P((dev_t dev, struct vnode **vpp));
/* cache_* may belong in namei.h. */
void cache_enter __P((struct vnode *dvp, struct vnode *vp,
@ -567,10 +569,6 @@ int vop_defaultop __P((struct vop_generic_args *ap));
int vop_null __P((struct vop_generic_args *ap));
int vop_panic __P((struct vop_generic_args *ap));
struct vnode *
checkalias __P((struct vnode *vp, udev_t nvp_rdev, struct mount *mp));
struct vnode *
checkalias2 __P((struct vnode *vp, dev_t nvp_rdev, struct mount *mp));
void vput __P((struct vnode *vp));
void vrele __P((struct vnode *vp));
void vref __P((struct vnode *vp));

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)mfs_vfsops.c 8.11 (Berkeley) 6/19/95
* $Id: mfs_vfsops.c,v 1.66 1999/07/20 09:47:55 phk Exp $
* $Id: mfs_vfsops.c,v 1.67 1999/08/24 18:35:33 phk Exp $
*/
@ -335,8 +335,7 @@ mfs_mount(mp, path, data, ndp, p)
dev->si_bsize_phys = DEV_BSIZE;
dev->si_bsize_best = BLKDEV_IOSIZE;
dev->si_bsize_max = MAXBSIZE;
if (checkalias(devvp, makeudev(253, mfs_minor++), (struct mount *)0))
panic("mfs_mount: dup dev");
addaliasu(devvp, makeudev(253, mfs_minor++));
devvp->v_data = mfsp;
mfsp->mfs_baseoff = args.base;
mfsp->mfs_size = args.size;

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
* $Id: ufs_vnops.c,v 1.120 1999/08/22 00:15:16 jdp Exp $
* $Id: ufs_vnops.c,v 1.121 1999/08/23 20:35:21 bde Exp $
*/
#include "opt_quota.h"
@ -2035,24 +2035,7 @@ ufs_vinit(mntp, specops, fifoops, vpp)
case VCHR:
case VBLK:
vp->v_op = specops;
nvp = checkalias(vp, ip->i_rdev, mntp);
if (nvp) {
/*
* Discard unneeded vnode, but save its inode.
* Note that the lock is carried over in the inode
* to the replacement vnode.
*/
nvp->v_data = vp->v_data;
vp->v_data = NULL;
vp->v_op = spec_vnodeop_p;
vrele(vp);
vgone(vp);
/*
* Reinitialize aliased inode.
*/
vp = nvp;
ip->i_vnode = vp;
}
addaliasu(vp, ip->i_rdev);
break;
case VFIFO:
vp->v_op = fifoops;

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)vm_swap.c 8.5 (Berkeley) 2/17/94
* $Id: vm_swap.c,v 1.82 1999/08/23 20:59:21 phk Exp $
* $Id: vm_swap.c,v 1.83 1999/08/24 05:58:35 green Exp $
*/
#include "opt_swap.h"
@ -349,11 +349,7 @@ swaponvp(p, vp, dev, nblks)
panic("Cannot get vnode for swapdev");
vp1 = nvp;
vp1->v_type = VBLK;
if ((nvp = checkalias(vp1, makeudev(BDEV_MAJOR, 0),
(struct mount *) 0))) {
vput(vp1);
vp1 = nvp;
}
addaliasu(vp1, makeudev(BDEV_MAJOR, 0));
swapdev_vp = vp1;
}
return (0);