summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2003-04-02 21:10:04 +0000
committerphk <phk@FreeBSD.org>2003-04-02 21:10:04 +0000
commit39cbb43bab476ff3c79356e36f26e51a6b90a692 (patch)
tree629b1f684f16eeb00568b7d1a2df6af64778ddf7 /sys
parentcedf04c4758318e15e1a5924e4226bb5a9699107 (diff)
downloadFreeBSD-src-39cbb43bab476ff3c79356e36f26e51a6b90a692.zip
FreeBSD-src-39cbb43bab476ff3c79356e36f26e51a6b90a692.tar.gz
Add handling for cancelled events in the g_call_me() methods.
Diffstat (limited to 'sys')
-rw-r--r--sys/geom/geom.h2
-rw-r--r--sys/geom/geom_bsd.c12
-rw-r--r--sys/geom/geom_disk.c17
-rw-r--r--sys/geom/geom_dump.c9
-rw-r--r--sys/geom/geom_event.c2
-rw-r--r--sys/geom/geom_int.h1
-rw-r--r--sys/geom/geom_mbr.c7
-rw-r--r--sys/geom/geom_pc98.c7
8 files changed, 43 insertions, 14 deletions
diff --git a/sys/geom/geom.h b/sys/geom/geom.h
index 55a1172..8795a07 100644
--- a/sys/geom/geom.h
+++ b/sys/geom/geom.h
@@ -221,7 +221,9 @@ void g_trace(int level, const char *, ...);
/* geom_event.c */
typedef void g_call_me_t(void *, int flag);
+#define EV_CANCEL 1
int g_call_me(g_call_me_t *func, void *arg, ...);
+void g_cancel_event(void *ref);
void g_orphan_provider(struct g_provider *pp, int error);
void g_waitidle(void);
diff --git a/sys/geom/geom_bsd.c b/sys/geom/geom_bsd.c
index 39f4222..f9e7df8 100644
--- a/sys/geom/geom_bsd.c
+++ b/sys/geom/geom_bsd.c
@@ -479,7 +479,7 @@ g_bsd_try(struct g_geom *gp, struct g_slicer *gsp, struct g_consumer *cp, int se
*/
static void
-g_bsd_ioctl(void *arg, int flag __unused)
+g_bsd_ioctl(void *arg, int flag)
{
struct bio *bp;
struct g_geom *gp;
@@ -494,11 +494,14 @@ g_bsd_ioctl(void *arg, int flag __unused)
int error, i;
uint64_t sum;
+ bp = arg;
+ if (flag == EV_CANCEL) {
+ g_io_deliver(bp, ENXIO);
+ return;
+ }
/* We don't need topology for now. */
g_topology_unlock();
- /* Get hold of the interesting bits from the bio. */
- bp = arg;
gp = bp->bio_to->geom;
gsp = gp->softc;
ms = gsp->softc;
@@ -608,7 +611,7 @@ g_bsd_diocbsdbb(dev_t dev, u_long cmd __unused, caddr_t data, int fflag __unused
* footshooting as best we can.
*/
static void
-g_bsd_hotwrite(void *arg, int flag __unused)
+g_bsd_hotwrite(void *arg, int flag)
{
struct bio *bp;
struct g_geom *gp;
@@ -619,6 +622,7 @@ g_bsd_hotwrite(void *arg, int flag __unused)
u_char *p;
int error;
+ KASSERT(flag != EV_CANCEL, ("g_bsd_hotwrite cancelled"));
bp = arg;
gp = bp->bio_to->geom;
gsp = gp->softc;
diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c
index 7ffd464..9b0d97e 100644
--- a/sys/geom/geom_disk.c
+++ b/sys/geom/geom_disk.c
@@ -307,7 +307,6 @@ g_disk_create(void *arg, int flag __unused)
gp->access = g_disk_access;
gp->softc = dp;
gp->dumpconf = g_disk_dumpconf;
- dp->d_geom = gp;
pp = g_new_providerf(gp, "%s", gp->name);
pp->mediasize = dp->d_mediasize;
pp->sectorsize = dp->d_sectorsize;
@@ -315,9 +314,10 @@ g_disk_create(void *arg, int flag __unused)
pp->flags |= G_PF_CANDELETE;
pp->stripeoffset = dp->d_stripeoffset;
pp->stripesize = dp->d_stripesize;
- g_error_provider(pp, 0);
if (bootverbose)
printf("GEOM: new disk %s\n", gp->name);
+ dp->d_geom = gp;
+ g_error_provider(pp, 0);
}
@@ -335,15 +335,28 @@ disk_create(int unit, struct disk *dp, int flags, void *unused __unused, void *
dp->d_devstat = devstat_new_entry(dp->d_name, dp->d_unit,
dp->d_sectorsize, DEVSTAT_ALL_SUPPORTED,
DEVSTAT_TYPE_DIRECT, DEVSTAT_PRIORITY_MAX);
+ dp->d_geom = NULL;
g_call_me(g_disk_create, dp, dp, NULL);
}
+/*
+ * XXX: There is a race if disk_destroy() is called while the g_disk_create()
+ * XXX: event is running. I belive the current result is that disk_destroy()
+ * XXX: actually doesn't do anything. Considering that the driver owns the
+ * XXX: struct disk and is likely to free it in a few moments, this can
+ * XXX: hardly be said to be optimal. To what extent we can sleep in
+ * XXX: disk_create() and disk_destroy() is currently undefined (but generally
+ * XXX: undesirable) so any solution seems to involve an intrusive decision.
+ */
void
disk_destroy(struct disk *dp)
{
struct g_geom *gp;
+ g_cancel_event(dp);
gp = dp->d_geom;
+ if (gp == NULL)
+ return;
gp->flags |= G_GEOM_WITHER;
gp->softc = NULL;
g_orphan_provider(LIST_FIRST(&gp->provider), ENXIO);
diff --git a/sys/geom/geom_dump.c b/sys/geom/geom_dump.c
index 1c39fc2..6d2a3de 100644
--- a/sys/geom/geom_dump.c
+++ b/sys/geom/geom_dump.c
@@ -101,11 +101,12 @@ g_confdot_class(struct sbuf *sb, struct g_class *mp)
}
void
-g_confdot(void *p, int flag __unused)
+g_confdot(void *p, int flag )
{
struct g_class *mp;
struct sbuf *sb;
+ KASSERT(flag != EV_CANCEL, ("g_confdot was cancelled"));
sb = p;
g_topology_assert();
sbuf_printf(sb, "digraph geom {\n");
@@ -143,11 +144,12 @@ g_conftxt_class(struct sbuf *sb, struct g_class *mp)
}
void
-g_conftxt(void *p, int flag __unused)
+g_conftxt(void *p, int flag)
{
struct g_class *mp;
struct sbuf *sb;
+ KASSERT(flag != EV_CANCEL, ("g_conftxt was cancelled"));
sb = p;
g_topology_assert();
LIST_FOREACH(mp, &g_classes, class)
@@ -263,9 +265,10 @@ g_conf_specific(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g
}
void
-g_confxml(void *p, int flag __unused)
+g_confxml(void *p, int flag)
{
+ KASSERT(flag != EV_CANCEL, ("g_confxml was cancelled"));
g_topology_assert();
g_conf_specific(p, NULL, NULL, NULL, NULL);
wakeup(p);
diff --git a/sys/geom/geom_event.c b/sys/geom/geom_event.c
index e0e6deb..deb8d7e 100644
--- a/sys/geom/geom_event.c
+++ b/sys/geom/geom_event.c
@@ -314,6 +314,8 @@ g_cancel_event(void *ref)
break;
if (ep->ref[n] == ref) {
TAILQ_REMOVE(&g_events, ep, events);
+ if (ep->event == EV_CALL_ME)
+ ep->func(ep->arg, EV_CANCEL);
g_free(ep);
break;
}
diff --git a/sys/geom/geom_int.h b/sys/geom/geom_int.h
index aa8877d..0f9695c 100644
--- a/sys/geom/geom_int.h
+++ b/sys/geom/geom_int.h
@@ -93,7 +93,6 @@ void g_conftxt(void *, int flag);
/* geom_event.c */
void g_event_init(void);
void g_post_event(enum g_events ev, ...);
-void g_cancel_event(void *ref);
void g_run_events(void);
void g_stall_events(void);
void g_release_events(void);
diff --git a/sys/geom/geom_mbr.c b/sys/geom/geom_mbr.c
index 5b24938..4eb7bd7 100644
--- a/sys/geom/geom_mbr.c
+++ b/sys/geom/geom_mbr.c
@@ -173,7 +173,7 @@ g_mbr_modify(struct g_geom *gp, struct g_mbr_softc *ms, u_char *sec0)
}
static void
-g_mbr_ioctl(void *arg, int flag __unused)
+g_mbr_ioctl(void *arg, int flag)
{
struct bio *bp;
struct g_geom *gp;
@@ -184,8 +184,11 @@ g_mbr_ioctl(void *arg, int flag __unused)
u_char *sec0;
int error;
- /* Get hold of the interesting bits from the bio. */
bp = arg;
+ if (flag == EV_CANCEL) {
+ g_io_deliver(bp, ENXIO);
+ return;
+ }
gp = bp->bio_to->geom;
gsp = gp->softc;
ms = gsp->softc;
diff --git a/sys/geom/geom_pc98.c b/sys/geom/geom_pc98.c
index 390ac95..db4b86c 100644
--- a/sys/geom/geom_pc98.c
+++ b/sys/geom/geom_pc98.c
@@ -160,7 +160,7 @@ g_pc98_modify(struct g_geom *gp, struct g_pc98_softc *ms, u_char *sec)
}
static void
-g_pc98_ioctl(void *arg, int flag __unused)
+g_pc98_ioctl(void *arg, int flag)
{
struct bio *bp;
struct g_geom *gp;
@@ -171,8 +171,11 @@ g_pc98_ioctl(void *arg, int flag __unused)
u_char *sec;
int error;
- /* Get hold of the interesting bits from the bio. */
bp = arg;
+ if (flag == EV_CANCEL) {
+ g_io_deliver(bp, ENXIO);
+ return;
+ }
gp = bp->bio_to->geom;
gsp = gp->softc;
ms = gsp->softc;
OpenPOWER on IntegriCloud