Add handling for cancelled events in the g_call_me() methods.

This commit is contained in:
Poul-Henning Kamp 2003-04-02 21:10:04 +00:00
parent afcbcfaed0
commit 316aed030e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=112989
8 changed files with 43 additions and 14 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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;