aboutsummaryrefslogtreecommitdiff
path: root/sys/geom/geom_sunlabel.c
diff options
context:
space:
mode:
authorPoul-Henning Kamp <phk@FreeBSD.org>2003-04-21 20:14:36 +0000
committerPoul-Henning Kamp <phk@FreeBSD.org>2003-04-21 20:14:36 +0000
commit989afda211ef4e5de1471f73dbcbbb34b484c70c (patch)
tree70e20148ad2414e7f2f35b841b82c1f25e741b05 /sys/geom/geom_sunlabel.c
parente72380dd0992f67b76723a2d2f6ef1fbb310787d (diff)
downloadsrc-989afda211ef4e5de1471f73dbcbbb34b484c70c.tar.gz
src-989afda211ef4e5de1471f73dbcbbb34b484c70c.zip
Implement a hotspot for the sunlabel.
This means that you can no longer trash your opened partitions by writing to the sunlabel through another partition. This is similar to the semantics implemented for BSD labels.
Notes
Notes: svn path=/head/; revision=113821
Diffstat (limited to 'sys/geom/geom_sunlabel.c')
-rw-r--r--sys/geom/geom_sunlabel.c41
1 files changed, 38 insertions, 3 deletions
diff --git a/sys/geom/geom_sunlabel.c b/sys/geom/geom_sunlabel.c
index f7a66676c46b..8e09362e7079 100644
--- a/sys/geom/geom_sunlabel.c
+++ b/sys/geom/geom_sunlabel.c
@@ -103,6 +103,41 @@ g_sunlabel_modify(struct g_geom *gp, struct g_sunlabel_softc *ms, u_char *sec0)
return (0);
}
+static void
+g_sunlabel_hotwrite(void *arg, int flag)
+{
+ struct bio *bp;
+ struct g_geom *gp;
+ struct g_slicer *gsp;
+ struct g_slice *gsl;
+ struct g_sunlabel_softc *ms;
+ u_char *p;
+ int error;
+
+ KASSERT(flag != EV_CANCEL, ("g_sunlabel_hotwrite cancelled"));
+ bp = arg;
+ gp = bp->bio_to->geom;
+ gsp = gp->softc;
+ ms = gsp->softc;
+ gsl = &gsp->slices[bp->bio_to->index];
+ /*
+ * XXX: For all practical purposes, this whould be equvivalent to
+ * XXX: "p = (u_char *)bp->bio_data;" because the label is always
+ * XXX: in the first sector and we refuse sectors smaller than the
+ * XXX: label.
+ */
+ p = (u_char *)bp->bio_data - (bp->bio_offset + gsl->offset);
+
+ g_topology_unlock();
+ error = g_sunlabel_modify(gp, ms, p);
+ g_topology_lock();
+ if (error) {
+ g_io_deliver(bp, EPERM);
+ return;
+ }
+ g_slice_finish_hot(bp);
+}
+
static int
g_sunlabel_start(struct bio *bp)
{
@@ -174,10 +209,10 @@ g_sunlabel_taste(struct g_class *mp, struct g_provider *pp, int flags)
if (LIST_EMPTY(&gp->provider)) {
g_std_spoiled(cp);
return (NULL);
-#ifdef notyet
} else {
- g_slice_conf_hot(gp, 0, 0, ms->sectorsize);
-#endif
+ g_slice_conf_hot(gp, 0, 0, SUN_SIZE,
+ G_SLICE_HOT_ALLOW, G_SLICE_HOT_DENY, G_SLICE_HOT_CALL);
+ gsp->hot = g_sunlabel_hotwrite;
}
return (gp);
}