FreeBSD/sys/fs/unionfs/union_subr.c
/*
 * Clean up the unionfs node.
 */
Clean up the unionfs node.
Clean up the unionfs node .
void
unionfs_noderem(struct vnode *vp, struct thread *td)
{
	int		count;
	struct unionfs_node *unp, *unp_t1, *unp_t2;
	struct unionfs_node_hashhead *hd;
	struct unionfs_node_status *unsp, *unsp_tmp;
	struct vnode   *lvp;
	struct vnode   *uvp;
	struct vnode   *dvp;
	VI_LOCK(vp);
	unp = VTOUNIONFS(vp);
	lvp = unp->un_lowervp;
	uvp = unp->un_uppervp;
	dvp = unp->un_dvp;
	unp->un_lowervp = unp->un_uppervp = NULLVP;
	vp->v_vnlock = &(vp->v_lock);
	vp->v_data = NULL;
	vp->v_object = NULL;
	VI_UNLOCK(vp);
	if (lvp != NULLVP)
		VOP_UNLOCK(lvp, LK_RELEASE);
	if (uvp != NULLVP)
		VOP_UNLOCK(uvp, LK_RELEASE);
	if (dvp != NULLVP && unp->un_hash.le_prev != NULL)
		unionfs_rem_cached_vnode(unp, dvp);
	if (lockmgr(vp->v_vnlock, LK_EXCLUSIVE, VI_MTX(vp)) != 0)
		panic("the lock for deletion is unacquirable.");
	if (lvp != NULLVP)
		vrele(lvp);
	if (uvp != NULLVP)
		vrele(uvp);
	if (dvp != NULLVP) {
		vrele(dvp);
		unp->un_dvp = NULLVP;
	}
	if (unp->un_path != NULL) {
		free(unp->un_path, M_UNIONFSPATH);
		unp->un_path = NULL;
	}
	if (unp->un_hashtbl != NULL) {
		for (count = 0; count <= unp->un_hashmask; count++) {
			hd = unp->un_hashtbl + count;
			LIST_FOREACH_SAFE(unp_t1, hd, un_hash, unp_t2) {
				LIST_REMOVE(unp_t1, un_hash);
				unp_t1->un_hash.le_next = NULL;
				unp_t1->un_hash.le_prev = NULL;
			}
		}
		hashdestroy(unp->un_hashtbl, M_UNIONFSHASH, unp->un_hashmask);
	}
	LIST_FOREACH_SAFE(unsp, &(unp->un_unshead), uns_list, unsp_tmp) {
		LIST_REMOVE(unsp, uns_list);
		free(unsp, M_TEMP);
	}
	free(unp, M_UNIONFSNODE);
}
void unionfs_noderem ( struct vnode * vp , struct thread * td ) { int count ; struct unionfs_node * unp , * unp_t1 , * unp_t2 ; struct unionfs_node_hashhead * hd ; struct unionfs_node_status * unsp , * unsp_tmp ; struct vnode * lvp ; struct vnode * uvp ; struct vnode * dvp ; VI_LOCK ( vp ) ; unp = VTOUNIONFS ( vp ) ; lvp = unp -> un_lowervp ; uvp = unp -> un_uppervp ; dvp = unp -> un_dvp ; unp -> un_lowervp = unp -> un_uppervp = NULLVP ; vp -> v_vnlock = & ( vp -> v_lock ) ; vp -> v_data = NULL ; vp -> v_object = NULL ; VI_UNLOCK ( vp ) ; if ( lvp != NULLVP ) VOP_UNLOCK ( lvp , LK_RELEASE ) ; if ( uvp != NULLVP ) VOP_UNLOCK ( uvp , LK_RELEASE ) ; if ( dvp != NULLVP && unp -> un_hash . le_prev != NULL ) unionfs_rem_cached_vnode ( unp , dvp ) ; if ( lockmgr ( vp -> v_vnlock , LK_EXCLUSIVE , VI_MTX ( vp ) ) != 0 ) panic ( " " ) ; if ( lvp != NULLVP ) vrele ( lvp ) ; if ( uvp != NULLVP ) vrele ( uvp ) ; if ( dvp != NULLVP ) { vrele ( dvp ) ; unp -> un_dvp = NULLVP ; } if ( unp -> un_path != NULL ) { free ( unp -> un_path , M_UNIONFSPATH ) ; unp -> un_path = NULL ; } if ( unp -> un_hashtbl != NULL ) { for ( count = 0 ; count <= unp -> un_hashmask ; count ++ ) { hd = unp -> un_hashtbl + count ; LIST_FOREACH_SAFE ( unp_t1 , hd , un_hash , unp_t2 ) { LIST_REMOVE ( unp_t1 , un_hash ) ; unp_t1 -> un_hash . le_next = NULL ; unp_t1 -> un_hash . le_prev = NULL ; } } hashdestroy ( unp -> un_hashtbl , M_UNIONFSHASH , unp -> un_hashmask ) ; } LIST_FOREACH_SAFE ( unsp , & ( unp -> un_unshead ) , uns_list , unsp_tmp ) { LIST_REMOVE ( unsp , uns_list ) ; free ( unsp , M_TEMP ) ; } free ( unp , M_UNIONFSNODE ) ; }
Clean up the unionfs node.
Clean up the unionfs node .
/*
	 * Use the interlock to protect the clearing of v_data to
	 * prevent faults in unionfs_lock().
	 */