summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2002-05-21 20:33:49 +0000
committerphk <phk@FreeBSD.org>2002-05-21 20:33:49 +0000
commit476ca0197fe439db32412d254212efdcc10bd9cf (patch)
treefec49ff015cfe691229ddfbcf6205b4f482aec1e /sys
parent4c8f46cf75901f6eeca741030d0075e8789c0566 (diff)
downloadFreeBSD-src-476ca0197fe439db32412d254212efdcc10bd9cf.zip
FreeBSD-src-476ca0197fe439db32412d254212efdcc10bd9cf.tar.gz
Introduce the concept of "magic spaces", and implement them in most of
the relevant classes. Some methods may implement various "magic spaces", this is reserved or magic areas on the disk, set a side for various and sundry purposes. A good example is the BSD disklabel and boot code on i386 which occupies a total of four magic spaces: boot1, the disklabel, the padding behind the disklabel and boot2. The reason we don't simply tell people to write the appropriate stuff on the underlying device is that (some of) the magic spaces might be real-time modifiable. It is for instance possible to change a disklabel while partitions are open, provided the open partitions do not get trampled in the process. Sponsored by: DARPA & NAI Labs.
Diffstat (limited to 'sys')
-rw-r--r--sys/geom/geom.h30
-rw-r--r--sys/geom/geom_bsd.c16
-rw-r--r--sys/geom/geom_dump.c19
-rw-r--r--sys/geom/geom_mbr.c8
-rw-r--r--sys/geom/geom_subr.c33
-rw-r--r--sys/geom/geom_sunlabel.c5
6 files changed, 108 insertions, 3 deletions
diff --git a/sys/geom/geom.h b/sys/geom/geom.h
index dafe65e..8fdf07d 100644
--- a/sys/geom/geom.h
+++ b/sys/geom/geom.h
@@ -61,6 +61,7 @@ struct g_event;
struct thread;
struct bio;
struct sbuf;
+struct g_magicspaces;
typedef struct g_geom * g_create_geom_t (struct g_class *mp,
@@ -122,6 +123,7 @@ struct g_geom {
void *softc;
struct g_event *event;
unsigned flags;
+ struct g_magicspaces *magicspaces;
#define G_GEOM_WITHER 1
};
@@ -172,6 +174,32 @@ struct g_provider {
off_t mediasize;
};
+/*
+ * Some methods may implement various "magic spaces", this is reserved
+ * or magic areas on the disk, set a side for various and sundry purposes.
+ * A good example is the BSD disklabel and boot code on i386 which occupies
+ * a total of four magic spaces: boot1, the disklabel, the padding behind
+ * the disklabel and boot2. The reason we don't simply tell people to
+ * write the appropriate stuff on the underlying device is that (some of)
+ * the magic spaces might be real-time modifiable. It is for instance
+ * possible to change a disklabel while partitions are open, provided
+ * the open partitions do not get trampled in the process.
+ */
+
+struct g_magicspace {
+ char name[8];
+ off_t offset;
+ u_int len;
+ u_int flags;
+};
+
+struct g_magicspaces {
+ uintptr_t geom_id;
+ char class[8];
+ uint nmagic;
+ struct g_magicspace *magicspace;
+};
+
/* geom_dump.c */
void g_hexdump(void *ptr, int length);
void g_trace(int level, char *, ...);
@@ -195,6 +223,7 @@ void g_silence(void);
int g_access_abs(struct g_consumer *cp, int read, int write, int exclusive);
int g_access_rel(struct g_consumer *cp, int read, int write, int exclusive);
void g_add_class(struct g_class *mp);
+int g_add_magicspace(struct g_geom *gp, u_int index, const char *name, off_t start, u_int len, u_int flags);
int g_attach(struct g_consumer *cp, struct g_provider *pp);
struct g_geom *g_create_geomf(char *class, struct g_provider *, char *fmt, ...);
void g_destroy_consumer(struct g_consumer *cp);
@@ -210,6 +239,7 @@ int g_haveattr_off_t(struct bio *bp, char *attribute, off_t val);
struct g_geom * g_insert_geom(char *class, struct g_consumer *cp);
struct g_consumer * g_new_consumer(struct g_geom *gp);
struct g_geom * g_new_geomf(struct g_class *mp, char *fmt, ...);
+int g_new_magicspaces(struct g_geom *gp, int nspaces);
struct g_provider * g_new_providerf(struct g_geom *gp, char *fmt, ...);
void g_sanity(void *ptr);
void g_spoil(struct g_provider *pp, struct g_consumer *cp);
diff --git a/sys/geom/geom_bsd.c b/sys/geom/geom_bsd.c
index 9b94e45..3e5ed6f 100644
--- a/sys/geom/geom_bsd.c
+++ b/sys/geom/geom_bsd.c
@@ -338,8 +338,22 @@ g_bsd_taste(struct g_class *mp, struct g_provider *pp, int flags)
error, (long long)mediasize);
}
error = g_bsd_try(gsp, cp, secsize, ms, secsize);
- if (error)
+ if (!error) {
+ g_new_magicspaces(gp, 4);
+ g_add_magicspace(gp, 0, "boot1", 0, 512, 0);
+ g_add_magicspace(gp, 1, "label", 512, 276, 0);
+ g_add_magicspace(gp, 2, "fill0", 748, 236, 0);
+ g_add_magicspace(gp, 3, "boot2", 1024, 7168, 0);
+ }
+ if (error) {
error = g_bsd_try(gsp, cp, secsize, ms, 64);
+ if (!error) {
+ g_new_magicspaces(gp, 3);
+ g_add_magicspace(gp, 0, "fill0", 0, 64, 0);
+ g_add_magicspace(gp, 1, "label", 64, 276, 0);
+ g_add_magicspace(gp, 2, "fill1", 340, 172, 0);
+ }
+ }
if (error)
break;
dl = &ms->ondisk;
diff --git a/sys/geom/geom_dump.c b/sys/geom/geom_dump.c
index 619e0ed..dcaee02 100644
--- a/sys/geom/geom_dump.c
+++ b/sys/geom/geom_dump.c
@@ -157,11 +157,30 @@ g_conf_geom(struct sbuf *sb, struct g_geom *gp, struct g_provider *pp, struct g_
{
struct g_consumer *cp2;
struct g_provider *pp2;
+ struct g_magicspace *gsp;
+ u_int u;
sbuf_printf(sb, " <geom id=\"%p\">\n", gp);
sbuf_printf(sb, " <class ref=\"%p\"/>\n", gp->class);
sbuf_printf(sb, " <name>%s</name>\n", gp->name);
sbuf_printf(sb, " <rank>%d</rank>\n", gp->rank);
+ if (gp->magicspaces) {
+ for (u = 0; u < gp->magicspaces->nmagic; u++) {
+ gsp = &gp->magicspaces->magicspace[u];
+ if (gsp->len == 0 || gsp->name == NULL)
+ continue;
+ sbuf_printf(sb, " <magicspace>\n");
+ sbuf_printf(sb, " <name>%.8s</name>\n",
+ gsp->name);
+ sbuf_printf(sb, " <offset>%lld</offset>\n",
+ (long long)gsp->offset);
+ sbuf_printf(sb, " <length>%u</length>\n",
+ gsp->len);
+ sbuf_printf(sb, " <flags>%u</flags>\n",
+ gsp->flags);
+ sbuf_printf(sb, " </magicspace>\n");
+ }
+ }
if (gp->dumpconf) {
sbuf_printf(sb, " <config>\n");
gp->dumpconf(sb, "\t", gp, NULL, NULL);
diff --git a/sys/geom/geom_mbr.c b/sys/geom/geom_mbr.c
index 2143bf0..fdb98aa 100644
--- a/sys/geom/geom_mbr.c
+++ b/sys/geom/geom_mbr.c
@@ -234,6 +234,10 @@ g_mbr_taste(struct g_class *mp, struct g_provider *pp, int insist)
g_topology_lock();
error = g_access_rel(cp, -1, 0, 0);
if (npart > 0) {
+ g_new_magicspaces(gp, 3);
+ g_add_magicspace(gp, 0, "boot", 0, DOSPARTOFF, 0);
+ g_add_magicspace(gp, 1, "mbr", DOSPARTOFF, 4 * 16, 0);
+ g_add_magicspace(gp, 2, "signature", 510, 2, 0);
LIST_FOREACH(pp, &gp->provider, provider)
g_error_provider(pp, 0);
return (gp);
@@ -380,8 +384,10 @@ g_mbrext_taste(struct g_class *mp, struct g_provider *pp, int insist __unused)
}
g_topology_lock();
error = g_access_rel(cp, -1, 0, 0);
- if (slice > 0)
+ if (slice > 0) {
+ /* XXX: add magic spaces */
return (gp);
+ }
g_topology_assert();
g_std_spoiled(cp);
diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c
index d672c3d..1b2dc2e 100644
--- a/sys/geom/geom_subr.c
+++ b/sys/geom/geom_subr.c
@@ -114,6 +114,35 @@ g_new_geomf(struct g_class *mp, char *fmt, ...)
return (gp);
}
+int
+g_new_magicspaces(struct g_geom *gp, int nspaces)
+{
+ gp->magicspaces = g_malloc(sizeof *gp->magicspaces, M_WAITOK | M_ZERO);
+ gp->magicspaces->magicspace =
+ g_malloc(sizeof *gp->magicspaces->magicspace * nspaces,
+ M_WAITOK | M_ZERO);
+ gp->magicspaces->geom_id = (uintptr_t)gp;
+ strncpy(gp->magicspaces->class, gp->class->name,
+ sizeof gp->magicspaces->class);
+ gp->magicspaces->nmagic = nspaces;
+ return (0);
+}
+
+int
+g_add_magicspace(struct g_geom *gp, u_int index, const char *name, off_t start, u_int len, u_int flags)
+{
+ struct g_magicspace *msp;
+
+ /* KASSERT gp->magicspaces != NULL */
+ /* KASSERT index < gp->magicspaces->nmagic */
+ msp = &gp->magicspaces->magicspace[index];
+ strncpy(msp->name, name, sizeof msp->name);
+ msp->offset = start;
+ msp->len = len;
+ msp->flags = flags;
+ return (0);
+}
+
void
g_destroy_geom(struct g_geom *gp)
{
@@ -129,6 +158,10 @@ g_destroy_geom(struct g_geom *gp)
gp->name, LIST_FIRST(&gp->consumer)));
LIST_REMOVE(gp, geom);
TAILQ_REMOVE(&geoms, gp, geoms);
+ if (gp->magicspaces) {
+ g_free(gp->magicspaces->magicspace);
+ g_free(gp->magicspaces);
+ }
g_free(gp->name);
g_free(gp);
}
diff --git a/sys/geom/geom_sunlabel.c b/sys/geom/geom_sunlabel.c
index b966e5b..6171ac8 100644
--- a/sys/geom/geom_sunlabel.c
+++ b/sys/geom/geom_sunlabel.c
@@ -179,8 +179,11 @@ g_sunlabel_taste(struct g_class *mp, struct g_provider *pp, int flags)
}
g_topology_lock();
error = g_access_rel(cp, -1, 0, 0);
- if (npart > 0)
+ if (npart > 0) {
+ g_new_magicspaces(gp, 1);
+ g_add_magicspace(gp, 0, "label", 0, 512, 0);
return (gp);
+ }
g_std_spoiled(cp);
return (NULL);
}
OpenPOWER on IntegriCloud