FreeBSD/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c
/*
 * gfs_dir_create: creates a new directory in the parent
 *
 *   size	- size of private data structure (v_data)
 *   pvp	- parent vnode (GFS directory)
 *   ops	- vnode operations vector
 *   entries	- NULL-terminated list of static entries (if any)
 *   maxlen	- maximum length of a directory entry
 *   readdir_cb	- readdir callback (see gfs_dir_readdir)
 *   inode_cb	- inode callback (see gfs_dir_readdir)
 *   lookup_cb	- lookup callback (see gfs_dir_lookup)
 *
 * In order to use this function, the first member of the private vnode
 * structure (v_data) must be a gfs_dir_t.  For each directory, there are
 * static entries, defined when the structure is initialized, and dynamic
 * entries, retrieved through callbacks.
 *
 * If a directory has static entries, then it must supply a inode callback,
 * which will compute the inode number based on the parent and the index.
 * For a directory with dynamic entries, the caller must supply a readdir
 * callback and a lookup callback.  If a static lookup fails, we fall back to
 * the supplied lookup callback, if any.
 *
 * This function also performs the same initialization as gfs_file_create().
 */


In order to use this function, the first member of the private vnode
structure (v_data) must be a gfs_dir_t.  For each directory, there are
static entries, defined when the structure is initialized, and dynamic
entries, retrieved through callbacks.

If a directory has static entries, then it must supply a inode callback,
which will compute the inode number based on the parent and the index.
For a directory with dynamic entries, the caller must supply a readdir
callback and a lookup callback.  If a static lookup fails, we fall back to
the supplied lookup callback, if any.

This function also performs the same initialization as gfs_file_create().
In order to use this function the first member of the private vnode structure ( v_data ) must be a gfs_dir_t . For each directory there are static entries defined when the structure is initialized and dynamic entries retrieved through callbacks . If a directory has static entries then it must supply a inode callback which will compute the inode number based on the parent and the index . For a directory with dynamic entries the caller must supply a readdir callback and a lookup callback . If a static lookup fails we fall back to the supplied lookup callback if any . This function also performs the same initialization as gfs_file_create () .
vnode_t *
gfs_dir_create(size_t struct_size, vnode_t *pvp, vfs_t *vfsp, vnodeops_t *ops,
    gfs_dirent_t *entries, gfs_inode_cb inode_cb, int maxlen,
    gfs_readdir_cb readdir_cb, gfs_lookup_cb lookup_cb)
{
	vnode_t *vp;
	gfs_dir_t *dp;
	gfs_dirent_t *de;
	vp = gfs_file_create(struct_size, pvp, vfsp, ops);
	vp->v_type = VDIR;
	dp = vp->v_data;
	dp->gfsd_file.gfs_type = GFS_DIR;
	dp->gfsd_maxlen = maxlen;
	if (entries != NULL) {
		for (de = entries; de->gfse_name != NULL; de++)
			dp->gfsd_nstatic++;
		dp->gfsd_static = kmem_alloc(
		    dp->gfsd_nstatic * sizeof (gfs_dirent_t), KM_SLEEP);
		bcopy(entries, dp->gfsd_static,
		    dp->gfsd_nstatic * sizeof (gfs_dirent_t));
	}
	dp->gfsd_readdir = readdir_cb;
	dp->gfsd_lookup = lookup_cb;
	dp->gfsd_inode = inode_cb;
	mutex_init(&dp->gfsd_lock, NULL, MUTEX_DEFAULT, NULL);
	return (vp);
}
vnode_t * gfs_dir_create ( size_t struct_size , vnode_t * pvp , vfs_t * vfsp , vnodeops_t * ops , gfs_dirent_t * entries , gfs_inode_cb inode_cb , int maxlen , gfs_readdir_cb readdir_cb , gfs_lookup_cb lookup_cb ) { vnode_t * vp ; gfs_dir_t * dp ; gfs_dirent_t * de ; vp = gfs_file_create ( struct_size , pvp , vfsp , ops ) ; vp -> v_type = VDIR ; dp = vp -> v_data ; dp -> gfsd_file . gfs_type = GFS_DIR ; dp -> gfsd_maxlen = maxlen ; if ( entries != NULL ) { for ( de = entries ; de -> gfse_name != NULL ; de ++ ) dp -> gfsd_nstatic ++ ; dp -> gfsd_static = kmem_alloc ( dp -> gfsd_nstatic * sizeof ( gfs_dirent_t ) , KM_SLEEP ) ; bcopy ( entries , dp -> gfsd_static , dp -> gfsd_nstatic * sizeof ( gfs_dirent_t ) ) ; } dp -> gfsd_readdir = readdir_cb ; dp -> gfsd_lookup = lookup_cb ; dp -> gfsd_inode = inode_cb ; mutex_init ( & dp -> gfsd_lock , NULL , MUTEX_DEFAULT , NULL ) ; return ( vp ) ; }
gfs_dir_create: creates a new directory in the parent
   size       - size of private data structure (v_data)
   pvp        - parent vnode (GFS directory)
   ops        - vnode operations vector
   entries    - NULL-terminated list of static entries (if any)
   maxlen     - maximum length of a directory entry
   readdir_cb - readdir callback (see gfs_dir_readdir)
   inode_cb   - inode callback (see gfs_dir_readdir)
   lookup_cb  - lookup callback (see gfs_dir_lookup)
gfs_dir_create : creates a new directory in the parent size - size of private data structure ( v_data ) pvp - parent vnode ( GFS directory ) ops - vnode operations vector entries - NULL - terminated list of static entries ( if any ) maxlen - maximum length of a directory entry readdir_cb - readdir callback ( see gfs_dir_readdir ) inode_cb - inode callback ( see gfs_dir_readdir ) lookup_cb - lookup callback ( see gfs_dir_lookup )