summaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--sys/geom/geom_aes.c4
-rw-r--r--sys/geom/geom_bsd.c4
-rw-r--r--sys/geom/geom_gpt.c2
-rw-r--r--sys/geom/geom_mbr.c4
-rw-r--r--sys/geom/geom_pc98.c5
-rw-r--r--sys/geom/geom_slice.c59
-rw-r--r--sys/geom/geom_slice.h9
-rw-r--r--sys/geom/geom_sunlabel.c2
8 files changed, 84 insertions, 5 deletions
diff --git a/sys/geom/geom_aes.c b/sys/geom/geom_aes.c
index 4304c2d..ed9e66e 100644
--- a/sys/geom/geom_aes.c
+++ b/sys/geom/geom_aes.c
@@ -317,6 +317,7 @@ g_aes_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
return (NULL);
}
buf = NULL;
+ g_topology_unlock();
while (1) {
if (gp->rank != 2)
break;
@@ -370,11 +371,14 @@ g_aes_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
*p++ = u >> 24;
}
}
+ g_topology_lock();
pp = g_new_providerf(gp, gp->name);
pp->mediasize = mediasize - sectorsize;
g_error_provider(pp, 0);
+ g_topology_unlock();
break;
}
+ g_topology_lock();
if (buf)
g_free(buf);
g_access_rel(cp, -1, 0, 0);
diff --git a/sys/geom/geom_bsd.c b/sys/geom/geom_bsd.c
index 6155d42..8c501e8 100644
--- a/sys/geom/geom_bsd.c
+++ b/sys/geom/geom_bsd.c
@@ -348,10 +348,12 @@ g_bsd_taste(struct g_class *mp, struct g_provider *pp, int flags)
if (ppp->p_size == 0)
continue;
npart++;
+ g_topology_lock();
pp2 = g_slice_addslice(gp, i,
((off_t)(ppp->p_offset - ppr->p_offset)) << 9ULL,
((off_t)ppp->p_size) << 9ULL,
"%s%c", pp->name, 'a' + i);
+ g_topology_unlock();
g_error_provider(pp2, 0);
}
ondisk2inram(ms);
@@ -388,8 +390,10 @@ g_bsd_taste(struct g_class *mp, struct g_provider *pp, int flags)
dl->d_checksum = 0;
dl->d_checksum = dkcksum(dl);
ms->inram = ms->ondisk;
+ g_topology_lock();
pp2 = g_slice_addslice(gp, RAW_PART,
0, mediasize, "%s%c", pp->name, 'a' + RAW_PART);
+ g_topology_unlock();
g_error_provider(pp2, 0);
npart = 1;
}
diff --git a/sys/geom/geom_gpt.c b/sys/geom/geom_gpt.c
index 99f67a4..3799a8b 100644
--- a/sys/geom/geom_gpt.c
+++ b/sys/geom/geom_gpt.c
@@ -220,9 +220,11 @@ g_gpt_taste(struct g_class *mp, struct g_provider *pp, int insist)
bcopy(ent, gs->part[i], hdr->hdr_entsz);
ps = (!memcmp(&ent->ent_type, &freebsd, sizeof(freebsd)))
? 's' : 'p';
+ g_topology_lock();
(void)g_slice_addslice(gp, i, ent->ent_lba_start * secsz,
(ent->ent_lba_end - ent->ent_lba_start + 1ULL) * secsz,
"%s%c%d", gp->name, ps, i + 1);
+ g_topology_unlock();
npart++;
}
diff --git a/sys/geom/geom_mbr.c b/sys/geom/geom_mbr.c
index 31ad77b..af56649 100644
--- a/sys/geom/geom_mbr.c
+++ b/sys/geom/geom_mbr.c
@@ -241,10 +241,12 @@ g_mbr_taste(struct g_class *mp, struct g_provider *pp, int insist)
g_mbr_print(i, dp + i);
npart++;
ms->type[i] = dp[i].dp_typ;
+ g_topology_lock();
pp2 = g_slice_addslice(gp, i,
((off_t)dp[i].dp_start) << 9ULL,
((off_t)dp[i].dp_size) << 9ULL,
"%ss%d", gp->name, i + 1);
+ g_topology_unlock();
}
break;
}
@@ -373,6 +375,7 @@ g_mbrext_taste(struct g_class *mp, struct g_provider *pp, int insist __unused)
g_mbrext_print(0, dp);
g_mbrext_print(1, dp + 1);
if (dp[0].dp_flag == 0 && dp[0].dp_size != 0) {
+ g_topology_lock();
pp2 = g_slice_addslice(gp, slice,
(((off_t)dp[0].dp_start) << 9ULL) + off,
((off_t)dp[0].dp_size) << 9ULL,
@@ -381,6 +384,7 @@ g_mbrext_taste(struct g_class *mp, struct g_provider *pp, int insist __unused)
strlen(gp->name) - 1,
gp->name,
slice + 5);
+ g_topology_unlock();
ms->type[slice] = dp[0].dp_typ;
slice++;
g_error_provider(pp2, 0);
diff --git a/sys/geom/geom_pc98.c b/sys/geom/geom_pc98.c
index fc3978e..4fcdf4b 100644
--- a/sys/geom/geom_pc98.c
+++ b/sys/geom/geom_pc98.c
@@ -155,16 +155,15 @@ g_pc98_taste(struct g_class *mp, struct g_provider *pp, int flags)
u = g_dec_le2(buf + 512 + 14 + i * 32);
if (u == 0)
continue;
- printf("Index: %d\n", i);
g_hexdump(buf+512 + i * 32, 32);
start = v * fwsect * fwhead * sectorsize;
length = (1 + u - v) * fwsect * fwhead * sectorsize;
- printf("c%d - c%d (%jx - %jx) = %s\n",
- v, u, (uintmax_t)start, (uintmax_t)length, buf + 512 + 16 + i * 32);
npart++;
+ g_topology_lock();
pp2 = g_slice_addslice(gp, i,
start, length,
"%ss%d", pp->name, 1 + i);
+ g_topology_unlock();
g_error_provider(pp2, 0);
}
break;
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);
}
diff --git a/sys/geom/geom_slice.h b/sys/geom/geom_slice.h
index 261adf5..8a1a27f 100644
--- a/sys/geom/geom_slice.h
+++ b/sys/geom/geom_slice.h
@@ -35,6 +35,9 @@
* $FreeBSD$
*/
+#ifndef _GEOM_GEOM_SLICE_H_
+#define _GEOM_GEOM_SLICE_H_
+
struct g_slice {
off_t offset;
off_t length;
@@ -45,6 +48,7 @@ typedef int g_slice_start_t (struct bio *bp);
struct g_slicer {
int nslice;
+ int nprovider;
off_t cfrontstuff;
off_t frontstuff;
struct g_slice *slices;
@@ -54,5 +58,10 @@ struct g_slicer {
g_dumpconf_t g_slice_dumpconf;
struct g_provider * g_slice_addslice(struct g_geom *gp, int index, off_t offset, off_t length, char *fmt, ...);
+int g_slice_config(struct g_geom *gp, int index, int how, off_t offset, off_t length, char *fmt, ...);
+#define G_SLICE_CONFIG_CHECK 0
+#define G_SLICE_CONFIG_SET 1
+#define G_SLICE_CONFIG_FORCE 2
struct g_geom * g_slice_new(struct g_class *mp, int slices, struct g_provider *pp, struct g_consumer **cpp, void *extrap, int extra, g_slice_start_t *start);
+#endif /* _GEOM_GEOM_SLICE_H_ */
diff --git a/sys/geom/geom_sunlabel.c b/sys/geom/geom_sunlabel.c
index d0b75f7..8b73091 100644
--- a/sys/geom/geom_sunlabel.c
+++ b/sys/geom/geom_sunlabel.c
@@ -169,10 +169,12 @@ g_sunlabel_taste(struct g_class *mp, struct g_provider *pp, int flags)
if (u == 0)
continue;
npart++;
+ g_topology_lock();
pp2 = g_slice_addslice(gp, i,
((off_t)v * csize) << 9ULL,
((off_t)u) << 9ULL,
"%s%c", pp->name, 'a' + i);
+ g_topology_unlock();
g_error_provider(pp2, 0);
}
break;
OpenPOWER on IntegriCloud