FreeBSD/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c
/*
 * gfs_dir_lookup_static()
 *
 * This routine looks up the provided name amongst the static entries
 * in the gfs directory and returns the corresponding vnode, if found.
 * The first argument to the function is a pointer to the comparison
 * function this function should use to decide if names are a match.
 *
 * If a match is found, and GFS_CACHE_VNODE is set and the vnode
 * exists, we simply return the existing vnode.  Otherwise, we call
 * the static entry's callback routine, caching the result if
 * necessary.  If the idx pointer argument is non-NULL, we use it to
 * return the index of the matching static entry.
 *
 * The gfs directory is expected to be locked by the caller prior to calling
 * this function.  The directory may be unlocked during the execution of
 * this function, but will be locked upon return from the function.
 *
 * This function returns 0 if a match is found, ENOENT if not.
 */
gfs_dir_lookup_static()
This routine looks up the provided name amongst the static entries
in the gfs directory and returns the corresponding vnode, if found.
The first argument to the function is a pointer to the comparison
function this function should use to decide if names are a match.

If a match is found, and GFS_CACHE_VNODE is set and the vnode
exists, we simply return the existing vnode.  Otherwise, we call
the static entry's callback routine, caching the result if
necessary.  If the idx pointer argument is non-NULL, we use it to
return the index of the matching static entry.

The gfs directory is expected to be locked by the caller prior to calling
this function.  The directory may be unlocked during the execution of
this function, but will be locked upon return from the function.

This function returns 0 if a match is found, ENOENT if not.
gfs_dir_lookup_static () This routine looks up the provided name amongst the static entries in the gfs directory and returns the corresponding vnode if found . The first argument to the function is a pointer to the comparison function this function should use to decide if names are a match . If a match is found and GFS_CACHE_VNODE is set and the vnode exists we simply return the existing vnode . Otherwise we call the static entry ' s callback routine caching the result if necessary . If the idx pointer argument is non - NULL we use it to return the index of the matching static entry . The gfs directory is expected to be locked by the caller prior to calling this function . The directory may be unlocked during the execution of this function but will be locked upon return from the function . This function returns 0 if a match is found ENOENT if not .
static int
gfs_dir_lookup_static(int (*compare)(const char *, const char *),
    gfs_dir_t *dp, const char *nm, vnode_t *dvp, int *idx,
    vnode_t **vpp, pathname_t *rpnp)
{
	gfs_dirent_t *ge;
	vnode_t *vp = NULL;
	int i;
	ASSERT(GFS_DIR_LOCKED(dp));
	for (i = 0; i < dp->gfsd_nstatic; i++) {
		ge = &dp->gfsd_static[i];
		if (compare(ge->gfse_name, nm) == 0) {
			if (rpnp)
				(void) strlcpy(rpnp->pn_buf, ge->gfse_name,
				    rpnp->pn_bufsize);
			if (ge->gfse_vnode) {
				ASSERT(ge->gfse_flags & GFS_CACHE_VNODE);
				vp = ge->gfse_vnode;
				VN_HOLD(vp);
				break;
			}
			gfs_dir_unlock(dp);
			vp = ge->gfse_ctor(dvp);
			gfs_dir_lock(dp);
			((gfs_file_t *)vp->v_data)->gfs_index = i;
			((gfs_file_t *)vp->v_data)->gfs_ino =
			    dp->gfsd_inode(dvp, i);
			if (ge->gfse_flags & GFS_CACHE_VNODE) {
				if (ge->gfse_vnode == NULL) {
					ge->gfse_vnode = vp;
				} else {
					vnode_t *oldvp = vp;
					vp = ge->gfse_vnode;
					VN_HOLD(vp);
					gfs_dir_unlock(dp);
					VN_RELE(oldvp);
					gfs_dir_lock(dp);
				}
			}
			break;
		}
	}
	if (vp == NULL)
		return (ENOENT);
	else if (idx)
		*idx = i;
	*vpp = vp;
	return (0);
}
static int gfs_dir_lookup_static ( int ( * compare ) ( const char * , const char * ) , gfs_dir_t * dp , const char * nm , vnode_t * dvp , int * idx , vnode_t * * vpp , pathname_t * rpnp ) { gfs_dirent_t * ge ; vnode_t * vp = NULL ; int i ; ASSERT ( GFS_DIR_LOCKED ( dp ) ) ; for ( i = 0 ; i < dp -> gfsd_nstatic ; i ++ ) { ge = & dp -> gfsd_static [ i ] ; if ( compare ( ge -> gfse_name , nm ) == 0 ) { if ( rpnp ) ( void ) strlcpy ( rpnp -> pn_buf , ge -> gfse_name , rpnp -> pn_bufsize ) ; if ( ge -> gfse_vnode ) { ASSERT ( ge -> gfse_flags & GFS_CACHE_VNODE ) ; vp = ge -> gfse_vnode ; VN_HOLD ( vp ) ; break ; } gfs_dir_unlock ( dp ) ; vp = ge -> gfse_ctor ( dvp ) ; gfs_dir_lock ( dp ) ; ( ( gfs_file_t * ) vp -> v_data ) -> gfs_index = i ; ( ( gfs_file_t * ) vp -> v_data ) -> gfs_ino = dp -> gfsd_inode ( dvp , i ) ; if ( ge -> gfse_flags & GFS_CACHE_VNODE ) { if ( ge -> gfse_vnode == NULL ) { ge -> gfse_vnode = vp ; } else { vnode_t * oldvp = vp ; vp = ge -> gfse_vnode ; VN_HOLD ( vp ) ; gfs_dir_unlock ( dp ) ; VN_RELE ( oldvp ) ; gfs_dir_lock ( dp ) ; } } break ; } } if ( vp == NULL ) return ( ENOENT ) ; else if ( idx ) * idx = i ; * vpp = vp ; return ( 0 ) ; }
gfs_dir_lookup_static()
 This routine looks up the provided name amongst the static entries
 in the gfs directory and returns the corresponding vnode, if found.
gfs_dir_lookup_static () This routine looks up the provided name amongst the static entries in the gfs directory and returns the corresponding vnode if found .
/*
	 * Search static entries.
	 */ /*
			 * We drop the directory lock, as the constructor will
			 * need to do KM_SLEEP allocations.  If we return from
			 * the constructor only to find that a parallel
			 * operation has completed, and GFS_CACHE_VNODE is set
			 * for this entry, we discard the result in favor of
			 * the cached vnode.
			 */ /* Set the inode according to the callback. */ /*
					 * A parallel constructor beat us to it;
					 * return existing vnode.  We have to be
					 * careful because we can't release the
					 * current vnode while holding the
					 * directory lock; its inactive routine
					 * will try to lock this directory.
					 */