if (olddp) {  LIST_FOREACH(p2, &allproc, p_list) { struct filedesc *fdp = p2->p_fd; if (fdp->fd_cdir && fdp->fd_cdir->v_id == olddp->v_id) { vrele(fdp->fd_cdir); vref(coveredvp); fdp->fd_cdir = coveredvp; } if (fdp->fd_rdir && fdp->fd_rdir->v_id == olddp->v_id) { vrele(fdp->fd_rdir); vref(coveredvp); fdp->fd_rdir = coveredvp; } } }
dounmount(struct mount *mp, int flags, struct proc *p, struct vnode *olddp){	struct vnode *coveredvp;	struct proc *p2;	int error;	int hadsyncer = 0; 	mp->mnt_flag &=~ MNT_ASYNC; 	cache_purgevfs(mp);	/* remove cache entries for this file sys */ 	if (mp->mnt_syncer != NULL) {		hadsyncer = 1; 		vgone(mp->mnt_syncer);		mp->mnt_syncer = NULL;	}	if (((mp->mnt_flag & MNT_RDONLY) ||	    (error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p)) == 0) || 	    (flags & MNT_FORCE)) 		error = VFS_UNMOUNT(mp, flags, p);	simple_lock(&mountlist_slock); 	if (error) { 		if ((mp->mnt_flag & MNT_RDONLY) == 0 && hadsyncer) 			(void) vfs_allocate_syncvnode(mp);		lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK,		    &mountlist_slock, p);		return (error);	}	CIRCLEQ_REMOVE(&mountlist, mp, mnt_list);	if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) {		if (olddp) {			/* 			 * Try to put processes back in a real directory			 * after a forced unmount.			 * XXX We're not holding a ref on olddp, which may			 * change, so compare id numbers.			 */			LIST_FOREACH(p2, &allproc, p_list) {				struct filedesc *fdp = p2->p_fd;				if (fdp->fd_cdir &&				    fdp->fd_cdir->v_id == olddp->v_id) {					vrele(fdp->fd_cdir);					vref(coveredvp);					fdp->fd_cdir = coveredvp;				}				if (fdp->fd_rdir &&				    fdp->fd_rdir->v_id == olddp->v_id) {					vrele(fdp->fd_rdir);					vref(coveredvp);					fdp->fd_rdir = coveredvp;				}			}		}		coveredvp->v_mountedhere = NULL; 		vrele(coveredvp); 	}	mp->mnt_vfc->vfc_refcount--;	if (mp->mnt_vnodelist.lh_first != NULL)		panic("unmount: dangling vnode");	lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_slock, p);	free(mp, M_MOUNT);	return (0);}