summaryrefslogtreecommitdiffstats
path: root/sys/geom/geom_slice.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2002-09-27 21:37:11 +0000
committerphk <phk@FreeBSD.org>2002-09-27 21:37:11 +0000
commitbd4b8491399a8df6b7aea34dc30845289f3bc0f8 (patch)
tree02c4bf4995be772bfd0fd8a2f45388a5e079ecb5 /sys/geom/geom_slice.c
parent577f8b1e73497700b0f10db6cf84bd6db96cd62c (diff)
downloadFreeBSD-src-bd4b8491399a8df6b7aea34dc30845289f3bc0f8.zip
FreeBSD-src-bd4b8491399a8df6b7aea34dc30845289f3bc0f8.tar.gz
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.
Diffstat (limited to 'sys/geom/geom_slice.c')
-rw-r--r--sys/geom/geom_slice.c59
1 files changed, 57 insertions, 2 deletions
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);
}
OpenPOWER on IntegriCloud