diff options
author | phk <phk@FreeBSD.org> | 2003-04-02 21:10:04 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2003-04-02 21:10:04 +0000 |
commit | 39cbb43bab476ff3c79356e36f26e51a6b90a692 (patch) | |
tree | 629b1f684f16eeb00568b7d1a2df6af64778ddf7 /sys/geom | |
parent | cedf04c4758318e15e1a5924e4226bb5a9699107 (diff) | |
download | FreeBSD-src-39cbb43bab476ff3c79356e36f26e51a6b90a692.zip FreeBSD-src-39cbb43bab476ff3c79356e36f26e51a6b90a692.tar.gz |
Add handling for cancelled events in the g_call_me() methods.
Diffstat (limited to 'sys/geom')
-rw-r--r-- | sys/geom/geom.h | 2 | ||||
-rw-r--r-- | sys/geom/geom_bsd.c | 12 | ||||
-rw-r--r-- | sys/geom/geom_disk.c | 17 | ||||
-rw-r--r-- | sys/geom/geom_dump.c | 9 | ||||
-rw-r--r-- | sys/geom/geom_event.c | 2 | ||||
-rw-r--r-- | sys/geom/geom_int.h | 1 | ||||
-rw-r--r-- | sys/geom/geom_mbr.c | 7 | ||||
-rw-r--r-- | sys/geom/geom_pc98.c | 7 |
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; |