FreeBSD/sys/geom/virstor/g_virstor.c
/*
 * Destroy geom - called internally
 * See g_virstor_destroy_geom for the other one
 */
Destroy geom - called internally
See g_virstor_destroy_geom for the other one
Destroy geom - called internally See g_virstor_destroy_geom for the other one
static int
virstor_geom_destroy(struct g_virstor_softc *sc, boolean_t force,
    boolean_t delay)
{
	struct g_provider *pp;
	struct g_geom *gp;
	u_int n;
	g_topology_assert();
	if (sc == NULL)
		return (ENXIO);
	pp = sc->provider;
	if (pp != NULL && (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)) {
		LOG_MSG(force ? LVL_WARNING : LVL_ERROR,
		    "Device %s is still open.", pp->name);
		if (!force)
			return (EBUSY);
	}
	for (n = 0; n < sc->n_components; n++) {
		if (sc->components[n].gcons != NULL)
			remove_component(sc, &sc->components[n], delay);
	}
	gp = sc->geom;
	gp->softc = NULL;
	KASSERT(sc->provider == NULL, ("Provider still exists for %s",
	    gp->name));
	mtx_lock(&sc->delayed_bio_q_mtx);
	while (!STAILQ_EMPTY(&sc->delayed_bio_q)) {
		struct g_virstor_bio_q *bq;
		bq = STAILQ_FIRST(&sc->delayed_bio_q);
		bq->bio->bio_error = ENOSPC;
		g_io_deliver(bq->bio, EIO);
		STAILQ_REMOVE_HEAD(&sc->delayed_bio_q, linkage);
		free(bq, M_GVIRSTOR);
	}
	mtx_unlock(&sc->delayed_bio_q_mtx);
	mtx_destroy(&sc->delayed_bio_q_mtx);
	free(sc->map, M_GVIRSTOR);
	free(sc->components, M_GVIRSTOR);
	bzero(sc, sizeof *sc);
	free(sc, M_GVIRSTOR);
	pp = LIST_FIRST(&gp->provider); 
	if (pp == NULL || (pp->acr == 0 && pp->acw == 0 && pp->ace == 0))
		LOG_MSG(LVL_DEBUG, "Device %s destroyed", gp->name);
	g_wither_geom(gp, ENXIO);
	return (0);
}
static int virstor_geom_destroy ( struct g_virstor_softc * sc , boolean_t force , boolean_t delay ) { struct g_provider * pp ; struct g_geom * gp ; u_int n ; g_topology_assert ( ) ; if ( sc == NULL ) return ( ENXIO ) ; pp = sc -> provider ; if ( pp != NULL && ( pp -> acr != 0 || pp -> acw != 0 || pp -> ace != 0 ) ) { LOG_MSG ( force ? LVL_WARNING : LVL_ERROR , " " , pp -> name ) ; if ( ! force ) return ( EBUSY ) ; } for ( n = 0 ; n < sc -> n_components ; n ++ ) { if ( sc -> components [ n ] . gcons != NULL ) remove_component ( sc , & sc -> components [ n ] , delay ) ; } gp = sc -> geom ; gp -> softc = NULL ; KASSERT ( sc -> provider == NULL , ( " " , gp -> name ) ) ; mtx_lock ( & sc -> delayed_bio_q_mtx ) ; while ( ! STAILQ_EMPTY ( & sc -> delayed_bio_q ) ) { struct g_virstor_bio_q * bq ; bq = STAILQ_FIRST ( & sc -> delayed_bio_q ) ; bq -> bio -> bio_error = ENOSPC ; g_io_deliver ( bq -> bio , EIO ) ; STAILQ_REMOVE_HEAD ( & sc -> delayed_bio_q , linkage ) ; free ( bq , M_GVIRSTOR ) ; } mtx_unlock ( & sc -> delayed_bio_q_mtx ) ; mtx_destroy ( & sc -> delayed_bio_q_mtx ) ; free ( sc -> map , M_GVIRSTOR ) ; free ( sc -> components , M_GVIRSTOR ) ; bzero ( sc , sizeof * sc ) ; free ( sc , M_GVIRSTOR ) ; pp = LIST_FIRST ( & gp -> provider ) ; if ( pp == NULL || ( pp -> acr == 0 && pp -> acw == 0 && pp -> ace == 0 ) ) LOG_MSG ( LVL_DEBUG , " " , gp -> name ) ; g_wither_geom ( gp , ENXIO ) ; return ( 0 ) ; }
Destroy geom - called internally
 See g_virstor_destroy_geom for the other one
Destroy geom - called internally See g_virstor_destroy_geom for the other one
/* XXX: This might or might not work, since we're called with
	 * the topology lock held. Also, it might panic the kernel if
	 * the error'd BIO is in softupdates code. */ /* We only offer one provider */