--- 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;