diff options
author | phk <phk@FreeBSD.org> | 2003-05-02 06:29:33 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2003-05-02 06:29:33 +0000 |
commit | 4ac5216f830b5fc89262d7720e52038ab0a96d9e (patch) | |
tree | 9f5de442aa37e33fa8f2e09720ff7872c65deea8 | |
parent | a50936449c3b72a8409e56cd2f6f3f777691331c (diff) | |
download | FreeBSD-src-4ac5216f830b5fc89262d7720e52038ab0a96d9e.zip FreeBSD-src-4ac5216f830b5fc89262d7720e52038ab0a96d9e.tar.gz |
Use a more tailored spoil routine for slices, and take advantage of
g_wither_geom() to do most of the work for us.
-rw-r--r-- | sys/geom/geom_slice.c | 34 | ||||
-rw-r--r-- | sys/geom/geom_slice.h | 1 |
2 files changed, 20 insertions, 15 deletions
diff --git a/sys/geom/geom_slice.c b/sys/geom/geom_slice.c index 0ff13b2..055facc 100644 --- a/sys/geom/geom_slice.c +++ b/sys/geom/geom_slice.c @@ -415,6 +415,21 @@ g_slice_conf_hot(struct g_geom *gp, u_int idx, off_t offset, off_t length, int r return (0); } +void +g_slice_spoiled(struct g_consumer *cp) +{ + struct g_geom *gp; + struct g_slicer *gsp; + + g_topology_assert(); + gp = cp->geom; + g_trace(G_T_TOPOLOGY, "g_slice_spoiled(%p/%s)", cp, gp->name); + gsp = gp->softc; + gp->softc = NULL; + g_slice_free(gsp); + g_wither_geom(gp, ENXIO); +} + struct g_geom * g_slice_new(struct g_class *mp, u_int slices, struct g_provider *pp, struct g_consumer **cpp, void *extrap, int extra, g_slice_start_t *start) { @@ -433,18 +448,14 @@ g_slice_new(struct g_class *mp, u_int slices, struct g_provider *pp, struct g_co gp->orphan = g_slice_orphan; gp->softc = gsp; gp->start = g_slice_start; - gp->spoiled = g_std_spoiled; + gp->spoiled = g_slice_spoiled; gp->dumpconf = g_slice_dumpconf; cp = g_new_consumer(gp); error = g_attach(cp, pp); if (error == 0) error = g_access_rel(cp, 1, 0, 0); if (error) { - if (cp->provider != NULL) - g_detach(cp); - g_destroy_consumer(cp); - g_slice_free(gsp); - g_destroy_geom(gp); + g_wither_geom(gp, ENXIO); return (NULL); } *vp = gsp->softc; @@ -455,20 +466,13 @@ g_slice_new(struct g_class *mp, u_int slices, struct g_provider *pp, struct g_co static void g_slice_orphan(struct g_consumer *cp) { - struct g_geom *gp; - struct g_provider *pp; - int error; g_trace(G_T_TOPOLOGY, "g_slice_orphan(%p/%s)", cp, cp->provider->name); g_topology_assert(); KASSERT(cp->provider->error != 0, ("g_slice_orphan with error == 0")); - gp = cp->geom; /* XXX: Not good enough we leak the softc and its suballocations */ - gp->flags |= G_GEOM_WITHER; - error = cp->provider->error; - LIST_FOREACH(pp, &gp->provider, provider) - g_orphan_provider(pp, error); - return; + g_slice_free(cp->geom->softc); + g_wither_geom(cp->geom, cp->provider->error); } diff --git a/sys/geom/geom_slice.h b/sys/geom/geom_slice.h index f6883e6..887cfac 100644 --- a/sys/geom/geom_slice.h +++ b/sys/geom/geom_slice.h @@ -70,6 +70,7 @@ struct g_slicer { g_dumpconf_t g_slice_dumpconf; int g_slice_config(struct g_geom *gp, u_int idx, int how, off_t offset, off_t length, u_int sectorsize, const char *fmt, ...); +void g_slice_spoiled(struct g_consumer *cp); #define G_SLICE_CONFIG_CHECK 0 #define G_SLICE_CONFIG_SET 1 #define G_SLICE_CONFIG_FORCE 2 |