--- sys/geom/cache/g_cache.c.orig 2011-05-11 11:46:33.000000000 +0700 +++ sys/geom/cache/g_cache.c 2012-05-22 19:22:38.000000000 +0700 @@ -83,6 +83,11 @@ SYSCTL_PROC(_kern_geom_cache, OID_AUTO, &g_cache_used_hi, 0, sysctl_handle_pct, "IU", ""); +static u_int g_cache_exclusive = 0; +TUNABLE_INT("kern.geom.cache.exclusive", &g_cache_exclusive); +SYSCTL_UINT(_kern_geom_cache, OID_AUTO, exclusive, CTLFLAG_RW | CTLFLAG_TUN, + &g_cache_exclusive, 0, "Use exclusive access to provider"); + static int g_cache_destroy(struct g_cache_softc *sc, boolean_t force); static g_ctl_destroy_geom_t g_cache_destroy_geom; @@ -536,6 +541,17 @@ g_cache_create(struct g_class *mp, struc return (NULL); } + if (g_cache_exclusive && ((i = g_access(cp, 1, 1, 1) != 0))) { + G_CACHE_DEBUG(0, "Cannot access %s (error=%d).", pp->name, i); + g_detach(cp); + g_destroy_consumer(cp); + g_destroy_provider(newpp); + mtx_destroy(&sc->sc_mtx); + g_free(sc); + g_destroy_geom(gp); + return (NULL); + } + g_error_provider(newpp, 0); G_CACHE_DEBUG(0, "Device %s created.", gp->name); callout_reset(&sc->sc_callout, g_cache_timeout * hz, g_cache_go, sc); @@ -547,6 +563,7 @@ g_cache_destroy(struct g_cache_softc *sc { struct g_geom *gp; struct g_provider *pp; + struct g_consumer *cp; struct g_cache_desc *dp, *dp2; int i; @@ -579,6 +596,9 @@ g_cache_destroy(struct g_cache_softc *sc } mtx_unlock(&sc->sc_mtx); mtx_destroy(&sc->sc_mtx); + cp = LIST_FIRST(&gp->consumer); + if (cp->acr > 0 && cp->acw > 0 && cp->ace > 0) + g_access(cp, -1, -1, -1); uma_zdestroy(sc->sc_zone); g_free(sc); gp->softc = NULL;