FreeBSD/sys/geom/sched/g_sched.c
/*
 * Support for dynamic switching of scheduling algorithms.
 * First initialize the data structures for the new algorithm,
 * then call g_sched_remove_locked() to flush all references
 * to the old one, finally link the new algorithm.
 */
Support for dynamic switching of scheduling algorithms.
First initialize the data structures for the new algorithm,
then call g_sched_remove_locked() to flush all references
to the old one, finally link the new algorithm.
Support for dynamic switching of scheduling algorithms . First initialize the data structures for the new algorithm then call g_sched_remove_locked () to flush all references to the old one finally link the new algorithm .
static int
g_sched_change_algo(struct gctl_req *req, struct g_class *mp,
    struct g_provider *pp, struct g_gsched *gsp)
{
	struct g_sched_softc *sc;
	struct g_geom *gp;
	struct g_hash *newh;
	void *data;
	u_long mask;
	int error = 0;
	gp = pp->geom;
	sc = gp->softc;
	data = gsp->gs_init(gp);
	if (data == NULL)
		return (ENOMEM);
	newh = g_sched_hash_init(gsp, &mask, HASH_WAITOK);
	if (gsp->gs_priv_size && !newh) {
		error = ENOMEM;
		goto fail;
	}
	g_sched_lock(gp);
	if (sc->sc_gsched) {	
		error = g_sched_remove_locked(gp, sc->sc_gsched);
		if (error)
			goto fail;
	}
	g_gsched_ref(gsp);
	sc->sc_gsched = gsp;
	sc->sc_data = data;
	sc->sc_hash = newh;
	sc->sc_mask = mask;
	g_sched_unlock(gp);
	return (0);
fail:
	if (newh)
		g_sched_hash_fini(gp, newh, mask, gsp, data);
	if (data)
		gsp->gs_fini(data);
	g_sched_unlock(gp);
	return (error);
}
static int g_sched_change_algo ( struct gctl_req * req , struct g_class * mp , struct g_provider * pp , struct g_gsched * gsp ) { struct g_sched_softc * sc ; struct g_geom * gp ; struct g_hash * newh ; void * data ; u_long mask ; int error = 0 ; gp = pp -> geom ; sc = gp -> softc ; data = gsp -> gs_init ( gp ) ; if ( data == NULL ) return ( ENOMEM ) ; newh = g_sched_hash_init ( gsp , & mask , HASH_WAITOK ) ; if ( gsp -> gs_priv_size && ! newh ) { error = ENOMEM ; goto fail ; } g_sched_lock ( gp ) ; if ( sc -> sc_gsched ) { error = g_sched_remove_locked ( gp , sc -> sc_gsched ) ; if ( error ) goto fail ; } g_gsched_ref ( gsp ) ; sc -> sc_gsched = gsp ; sc -> sc_data = data ; sc -> sc_hash = newh ; sc -> sc_mask = mask ; g_sched_unlock ( gp ) ; return ( 0 ) ; fail : if ( newh ) g_sched_hash_fini ( gp , newh , mask , gsp , data ) ; if ( data ) gsp -> gs_fini ( data ) ; g_sched_unlock ( gp ) ; return ( error ) ; }
Support for dynamic switching of scheduling algorithms.
Support for dynamic switching of scheduling algorithms .
/* can be NULL in some cases */