From bd4b8491399a8df6b7aea34dc30845289f3bc0f8 Mon Sep 17 00:00:00 2001 From: phk Date: Fri, 27 Sep 2002 21:37:11 +0000 Subject: Add the new g_slice_config() call, which can add/delete/change a slice, with support for trying, doing and forcing. This will eventually replace g_slice_addslice() which gets changed from grabbing topology to requing it in this commit as well. Sponsored by: DARPA & NAI Labs. --- sys/geom/geom_slice.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) (limited to 'sys/geom/geom_slice.c') diff --git a/sys/geom/geom_slice.c b/sys/geom/geom_slice.c index 5bd20ea..c91c1cf 100644 --- a/sys/geom/geom_slice.c +++ b/sys/geom/geom_slice.c @@ -226,6 +226,62 @@ g_slice_dumpconf(struct sbuf *sb, char *indent, struct g_geom *gp, struct g_cons } } +int +g_slice_config(struct g_geom *gp, int index, int how, off_t offset, off_t length, char *fmt, ...) +{ + struct g_provider *pp; + struct g_slicer *gsp; + struct g_slice *gsl; + va_list ap; + struct sbuf *sb; + int error, acc; + + g_trace(G_T_TOPOLOGY, "g_slice_config()"); + g_topology_assert(); + gsp = gp->softc; + error = 0; + if (index >= gsp->nslice) + return(EINVAL); + gsl = &gsp->slices[index]; + pp = gsl->provider; + if (pp != NULL) + acc = pp->acr + pp->acw + pp->ace; + else + acc = 0; + if (acc != 0 && how != G_SLICE_CONFIG_FORCE) { + if (length < gsl->length) + return(EBUSY); + if (offset != gsl->offset) + return(EBUSY); + } + /* XXX: check offset + length <= MEDIASIZE */ + if (how == G_SLICE_CONFIG_CHECK) + return (0); + gsl->length = length; + gsl->offset = offset; + if (length != 0 && pp != NULL) + return (0); + if (length == 0 && pp == NULL) + return (0); + if (length == 0 && pp != NULL) { + g_orphan_provider(pp, ENXIO); + gsl->provider = NULL; + gsp->nprovider--; + return (0); + } + va_start(ap, fmt); + sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); + sbuf_vprintf(sb, fmt, ap); + sbuf_finish(sb); + pp = g_new_providerf(gp, sbuf_data(sb)); + pp->index = index; + gsl->provider = pp; + gsp->nprovider++; + g_error_provider(pp, 0); + sbuf_delete(sb); + return(0); +} + struct g_provider * g_slice_addslice(struct g_geom *gp, int index, off_t offset, off_t length, char *fmt, ...) { @@ -235,7 +291,7 @@ g_slice_addslice(struct g_geom *gp, int index, off_t offset, off_t length, char struct sbuf *sb; g_trace(G_T_TOPOLOGY, "g_slice_addslice()"); - g_topology_lock(); + g_topology_assert(); gsp = gp->softc; va_start(ap, fmt); sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); @@ -248,7 +304,6 @@ g_slice_addslice(struct g_geom *gp, int index, off_t offset, off_t length, char gsp->slices[index].offset = offset; gsp->slices[index].provider = pp; sbuf_delete(sb); - g_topology_unlock(); return(pp); } -- cgit v1.1