FreeBSD/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c
/*
 * gfs_file_inactive()
 *
 * Called from the VOP_RECLAIM() routine.  If necessary, this routine will
 * remove the given vnode from the parent directory and clean up any references
 * in the VFS layer.
 *
 * If the vnode was not removed (due to a race with vget), then NULL is
 * returned.  Otherwise, a pointer to the private data is returned.
 */


If the vnode was not removed (due to a race with vget), then NULL is
returned.  Otherwise, a pointer to the private data is returned.
If the vnode was not removed ( due to a race with vget ) then NULL is returned . Otherwise a pointer to the private data is returned .
void *
gfs_file_inactive(vnode_t *vp)
{
	int i;
	gfs_dirent_t *ge = NULL;
	gfs_file_t *fp = vp->v_data;
	gfs_dir_t *dp = NULL;
	void *data;
	if (fp->gfs_parent == NULL || (vp->v_flag & V_XATTRDIR))
		goto found;
	if ((dp = fp->gfs_parent->v_data) == NULL)
		return (NULL);
	gfs_dir_lock(dp);
	for (i = 0; i < dp->gfsd_nstatic; i++)  {
		ge = &dp->gfsd_static[i];
		if (ge->gfse_vnode == vp)
			goto found;
	}
	ge = NULL;
found:
#ifdef TODO
	if (vp->v_flag & V_XATTRDIR)
		VI_LOCK(fp->gfs_parent);
#endif
	VI_LOCK(vp);
	data = vp->v_data;
	if (ge != NULL) {
		ge->gfse_vnode = NULL;
	}
	VI_UNLOCK(vp);
	if (fp->gfs_parent) {
		if (dp)
			gfs_dir_unlock(dp);
		VOP_UNLOCK(vp, 0);
		VN_RELE(fp->gfs_parent);
		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
	} else {
		ASSERT(vp->v_vfsp != NULL);
#ifdef illumos
		VFS_RELE(vp->v_vfsp);
#endif
	}
#ifdef TODO
	if (vp->v_flag & V_XATTRDIR)
		VI_UNLOCK(fp->gfs_parent);
#endif
	return (data);
}
void * gfs_file_inactive ( vnode_t * vp ) { int i ; gfs_dirent_t * ge = NULL ; gfs_file_t * fp = vp -> v_data ; gfs_dir_t * dp = NULL ; void * data ; if ( fp -> gfs_parent == NULL || ( vp -> v_flag & V_XATTRDIR ) ) goto found ; if ( ( dp = fp -> gfs_parent -> v_data ) == NULL ) return ( NULL ) ; gfs_dir_lock ( dp ) ; for ( i = 0 ; i < dp -> gfsd_nstatic ; i ++ ) { ge = & dp -> gfsd_static [ i ] ; if ( ge -> gfse_vnode == vp ) goto found ; } ge = NULL ; found : #ifdef TODO if ( vp -> v_flag & V_XATTRDIR ) VI_LOCK ( fp -> gfs_parent ) ; #endif VI_LOCK ( vp ) ; data = vp -> v_data ; if ( ge != NULL ) { ge -> gfse_vnode = NULL ; } VI_UNLOCK ( vp ) ; if ( fp -> gfs_parent ) { if ( dp ) gfs_dir_unlock ( dp ) ; VOP_UNLOCK ( vp , 0 ) ; VN_RELE ( fp -> gfs_parent ) ; vn_lock ( vp , LK_EXCLUSIVE | LK_RETRY ) ; } else { ASSERT ( vp -> v_vfsp != NULL ) ; #ifdef illumos VFS_RELE ( vp -> v_vfsp ) ; #endif } #ifdef TODO if ( vp -> v_flag & V_XATTRDIR ) VI_UNLOCK ( fp -> gfs_parent ) ; #endif return ( data ) ; }
gfs_file_inactive()
 Called from the VOP_RECLAIM() routine.
gfs_file_inactive () Called from the VOP_RECLAIM () routine .
/*
	 * XXX cope with a FreeBSD-specific race wherein the parent's
	 * snapshot data can be freed before the parent is
	 */ /*
	 * First, see if this vnode is cached in the parent.
	 */ /*
	 * Find it in the set of static entries.
	 */ /*
	 * If 'ge' is NULL, then it is a dynamic entry.
	 */ /*
	 * Really remove this vnode
	 */ /*
		 * If this was a statically cached entry, simply set the
		 * cached vnode to NULL.
		 */ /*
	 * Free vnode and release parent
	 */