FreeBSD/sys/fs/devfs/devfs_vnops.c
/*
 * Revoke is called on a tty when a terminal session ends.  The vnode
 * is orphaned by setting v_op to deadfs so we need to let go of it
 * as well so that we create a new one next time around.
 *
 */
Revoke is called on a tty when a terminal session ends.  The vnode
is orphaned by setting v_op to deadfs so we need to let go of it
as well so that we create a new one next time around.
Revoke is called on a tty when a terminal session ends . The vnode is orphaned by setting v_op to deadfs so we need to let go of it as well so that we create a new one next time around .
static int
devfs_revoke(struct vop_revoke_args *ap)
{
	struct vnode *vp = ap->a_vp, *vp2;
	struct cdev *dev;
	struct cdev_priv *cdp;
	struct devfs_dirent *de;
	u_int i;
	KASSERT((ap->a_flags & REVOKEALL) != 0, ("devfs_revoke !REVOKEALL"));
	dev = vp->v_rdev;
	cdp = cdev2priv(dev);
	dev_lock();
	cdp->cdp_inuse++;
	dev_unlock();
	vhold(vp);
	vgone(vp);
	vdrop(vp);
	VOP_UNLOCK(vp,0);
 loop:
	for (;;) {
		mtx_lock(&devfs_de_interlock);
		dev_lock();
		vp2 = NULL;
		for (i = 0; i <= cdp->cdp_maxdirent; i++) {
			de = cdp->cdp_dirents[i];
			if (de == NULL)
				continue;
			vp2 = de->de_vnode;
			if (vp2 != NULL) {
				dev_unlock();
				VI_LOCK(vp2);
				mtx_unlock(&devfs_de_interlock);
				if (vget(vp2, LK_EXCLUSIVE | LK_INTERLOCK,
				    curthread))
					goto loop;
				vhold(vp2);
				vgone(vp2);
				vdrop(vp2);
				vput(vp2);
				break;
			} 
		}
		if (vp2 != NULL) {
			continue;
		}
		dev_unlock();
		mtx_unlock(&devfs_de_interlock);
		break;
	}
	dev_lock();
	cdp->cdp_inuse--;
	if (!(cdp->cdp_flags & CDP_ACTIVE) && cdp->cdp_inuse == 0) {
		TAILQ_REMOVE(&cdevp_list, cdp, cdp_list);
		dev_unlock();
		dev_rel(&cdp->cdp_c);
	} else
		dev_unlock();
	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
	return (0);
}
static int devfs_revoke ( struct vop_revoke_args * ap ) { struct vnode * vp = ap -> a_vp , * vp2 ; struct cdev * dev ; struct cdev_priv * cdp ; struct devfs_dirent * de ; u_int i ; KASSERT ( ( ap -> a_flags & REVOKEALL ) != 0 , ( " " ) ) ; dev = vp -> v_rdev ; cdp = cdev2priv ( dev ) ; dev_lock ( ) ; cdp -> cdp_inuse ++ ; dev_unlock ( ) ; vhold ( vp ) ; vgone ( vp ) ; vdrop ( vp ) ; VOP_UNLOCK ( vp , 0 ) ; loop : for ( ; ; ) { mtx_lock ( & devfs_de_interlock ) ; dev_lock ( ) ; vp2 = NULL ; for ( i = 0 ; i <= cdp -> cdp_maxdirent ; i ++ ) { de = cdp -> cdp_dirents [ i ] ; if ( de == NULL ) continue ; vp2 = de -> de_vnode ; if ( vp2 != NULL ) { dev_unlock ( ) ; VI_LOCK ( vp2 ) ; mtx_unlock ( & devfs_de_interlock ) ; if ( vget ( vp2 , LK_EXCLUSIVE | LK_INTERLOCK , curthread ) ) goto loop ; vhold ( vp2 ) ; vgone ( vp2 ) ; vdrop ( vp2 ) ; vput ( vp2 ) ; break ; } } if ( vp2 != NULL ) { continue ; } dev_unlock ( ) ; mtx_unlock ( & devfs_de_interlock ) ; break ; } dev_lock ( ) ; cdp -> cdp_inuse -- ; if ( ! ( cdp -> cdp_flags & CDP_ACTIVE ) && cdp -> cdp_inuse == 0 ) { TAILQ_REMOVE ( & cdevp_list , cdp , cdp_list ) ; dev_unlock ( ) ; dev_rel ( & cdp -> cdp_c ) ; } else dev_unlock ( ) ; vn_lock ( vp , LK_EXCLUSIVE | LK_RETRY ) ; return ( 0 ) ; }
Revoke is called on a tty when a terminal session ends.
Revoke is called on a tty when a terminal session ends .