FreeBSD/sys/geom/sched/g_sched.c
/*
 * Create a geom node for the device passed as *pp.
 * If successful, add a reference to this gsp.
 */
Create a geom node for the device passed as *pp.
If successful, add a reference to this gsp.
Create a geom node for the device passed as * pp . If successful add a reference to this gsp .
static int
g_sched_create(struct gctl_req *req, struct g_class *mp,
    struct g_provider *pp, struct g_gsched *gsp, int proxy)
{
	struct g_sched_softc *sc = NULL;
	struct g_geom *gp, *dstgp;
	struct g_provider *newpp = NULL;
	struct g_consumer *cp = NULL;
	char name[64];
	int error;
	g_topology_assert();
	snprintf(name, sizeof(name), "%s%s", pp->name, G_SCHED_SUFFIX);
	LIST_FOREACH(gp, &mp->geom, geom) {
		if (strcmp(gp->name, name) == 0) {
			gctl_error(req, "Geom %s already exists.",
			    name);
			return (EEXIST);
		}
	}
	gp = g_new_geomf(mp, "%s", name);
	dstgp = proxy ? pp->geom : gp; 
	sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO);
	sc->sc_gsched = gsp;
	sc->sc_data = gsp->gs_init(gp);
	if (sc->sc_data == NULL) {
		error = ENOMEM;
		goto fail;
	}
	sc->sc_hash = g_sched_hash_init(gsp, &sc->sc_mask, HASH_WAITOK);
	mtx_init(&sc->sc_mtx, "g_sched_mtx", NULL, MTX_DEF);
	gp->softc = sc;
	gp->start = g_sched_start;
	gp->orphan = g_sched_orphan;
	gp->access = g_sched_access;
	gp->dumpconf = g_sched_dumpconf;
	newpp = g_new_providerf(dstgp, "%s", gp->name);
	newpp->mediasize = pp->mediasize;
	newpp->sectorsize = pp->sectorsize;
	cp = g_new_consumer(gp);
	error = g_attach(cp, proxy ? newpp : pp);
	if (error != 0) {
		gctl_error(req, "Cannot attach to provider %s.",
		    pp->name);
		goto fail;
	}
	g_error_provider(newpp, 0);
	if (proxy) {
		error = g_insert_proxy(gp, newpp, dstgp, pp, cp);
		if (error)
			goto fail;
	}
	G_SCHED_DEBUG(0, "Device %s created.", gp->name);
	g_gsched_ref(gsp);
	return (0);
fail:
	if (cp != NULL) {
		if (cp->provider != NULL)
			g_detach(cp);
		g_destroy_consumer(cp);
	}
	if (newpp != NULL)
		g_destroy_provider(newpp);
	if (sc->sc_hash)
		g_sched_hash_fini(gp, sc->sc_hash, sc->sc_mask,
		    gsp, sc->sc_data);
	if (sc->sc_data)
		gsp->gs_fini(sc->sc_data);
	g_free(gp->softc);
	g_destroy_geom(gp);
	return (error);
}
static int g_sched_create ( struct gctl_req * req , struct g_class * mp , struct g_provider * pp , struct g_gsched * gsp , int proxy ) { struct g_sched_softc * sc = NULL ; struct g_geom * gp , * dstgp ; struct g_provider * newpp = NULL ; struct g_consumer * cp = NULL ; char name [ 64 ] ; int error ; g_topology_assert ( ) ; snprintf ( name , sizeof ( name ) , " " , pp -> name , G_SCHED_SUFFIX ) ; LIST_FOREACH ( gp , & mp -> geom , geom ) { if ( strcmp ( gp -> name , name ) == 0 ) { gctl_error ( req , " " , name ) ; return ( EEXIST ) ; } } gp = g_new_geomf ( mp , " " , name ) ; dstgp = proxy ? pp -> geom : gp ; sc = g_malloc ( sizeof ( * sc ) , M_WAITOK | M_ZERO ) ; sc -> sc_gsched = gsp ; sc -> sc_data = gsp -> gs_init ( gp ) ; if ( sc -> sc_data == NULL ) { error = ENOMEM ; goto fail ; } sc -> sc_hash = g_sched_hash_init ( gsp , & sc -> sc_mask , HASH_WAITOK ) ; mtx_init ( & sc -> sc_mtx , " " , NULL , MTX_DEF ) ; gp -> softc = sc ; gp -> start = g_sched_start ; gp -> orphan = g_sched_orphan ; gp -> access = g_sched_access ; gp -> dumpconf = g_sched_dumpconf ; newpp = g_new_providerf ( dstgp , " " , gp -> name ) ; newpp -> mediasize = pp -> mediasize ; newpp -> sectorsize = pp -> sectorsize ; cp = g_new_consumer ( gp ) ; error = g_attach ( cp , proxy ? newpp : pp ) ; if ( error != 0 ) { gctl_error ( req , " " , pp -> name ) ; goto fail ; } g_error_provider ( newpp , 0 ) ; if ( proxy ) { error = g_insert_proxy ( gp , newpp , dstgp , pp , cp ) ; if ( error ) goto fail ; } G_SCHED_DEBUG ( 0 , " " , gp -> name ) ; g_gsched_ref ( gsp ) ; return ( 0 ) ; fail : if ( cp != NULL ) { if ( cp -> provider != NULL ) g_detach ( cp ) ; g_destroy_consumer ( cp ) ; } if ( newpp != NULL ) g_destroy_provider ( newpp ) ; if ( sc -> sc_hash ) g_sched_hash_fini ( gp , sc -> sc_hash , sc -> sc_mask , gsp , sc -> sc_data ) ; if ( sc -> sc_data ) gsp -> gs_fini ( sc -> sc_data ) ; g_free ( gp -> softc ) ; g_destroy_geom ( gp ) ; return ( error ) ; }
Create a geom node for the device passed as *pp.
Create a geom node for the device passed as * pp .
/* where do we link the provider */ /*
	 * Do not initialize the flush mechanism, will be initialized
	 * on the first insertion on the hash table.
	 */