Change events to have an array of "void *" references, and give the

event posting functions varargs to fill these.

Attribute g_call_me() to appropriate g_geom's where necessary.

Add a flag argument to g_call_me() methods which will be used to signal
cancellation of events in the future.

This commit should be a no-op.
This commit is contained in:
Poul-Henning Kamp 2003-04-02 20:41:18 +00:00
parent 7d7d429762
commit afcbcfaed0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=112988
11 changed files with 90 additions and 98 deletions

View File

@ -220,8 +220,8 @@ void g_trace(int level, const char *, ...);
/* geom_event.c */
typedef void g_call_me_t(void *);
int g_call_me(g_call_me_t *func, void *arg);
typedef void g_call_me_t(void *, int flag);
int g_call_me(g_call_me_t *func, void *arg, ...);
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)
g_bsd_ioctl(void *arg, int flag __unused)
{
struct bio *bp;
struct g_geom *gp;
@ -608,7 +608,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)
g_bsd_hotwrite(void *arg, int flag __unused)
{
struct bio *bp;
struct g_geom *gp;
@ -682,7 +682,7 @@ g_bsd_start(struct bio *bp)
/* We do not allow deleting our hot spots */
return (EPERM);
case BIO_WRITE:
g_call_me(g_bsd_hotwrite, bp);
g_call_me(g_bsd_hotwrite, bp, gp, NULL);
return (EJUSTRETURN);
case BIO_GETATTR:
if (g_handleattr(bp, "BSD::labelsum", ms->labelsum,
@ -723,7 +723,7 @@ g_bsd_start(struct bio *bp)
* some I/O requests. Ask the event-handler to schedule
* us in a less restricted environment.
*/
error = g_call_me(g_bsd_ioctl, bp);
error = g_call_me(g_bsd_ioctl, bp, gp, NULL);
if (error)
g_io_deliver(bp, error);
/*

View File

@ -294,7 +294,7 @@ g_disk_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, struct g
}
static void
g_disk_create(void *arg)
g_disk_create(void *arg, int flag __unused)
{
struct g_geom *gp;
struct g_provider *pp;
@ -335,7 +335,7 @@ 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);
g_call_me(g_disk_create, dp);
g_call_me(g_disk_create, dp, dp, NULL);
}
void
@ -351,7 +351,7 @@ disk_destroy(struct disk *dp)
}
static void
g_kern_disks(void *p)
g_kern_disks(void *p, int flag __unused)
{
struct sbuf *sb;
struct g_geom *gp;
@ -376,7 +376,7 @@ sysctl_disks(SYSCTL_HANDLER_ARGS)
sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
sbuf_clear(sb);
error = g_call_me(g_kern_disks, sb);
error = g_call_me(g_kern_disks, sb, NULL);
while (!error && !sbuf_done(sb)) {
tsleep(sb, PZERO, "kern.disks", hz);
}

View File

@ -40,6 +40,8 @@
#ifdef _KERNEL
#include <sys/queue.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
typedef int disk_open_t(struct disk *);
typedef int disk_close_t(struct disk *);
@ -60,6 +62,8 @@ struct disk {
u_int d_flags;
const char *d_name;
u_int d_unit;
struct bio_queue_head *d_queue;
struct mtx *d_lock;
/* Disk methods */
disk_open_t *d_open;

View File

@ -101,7 +101,7 @@ g_confdot_class(struct sbuf *sb, struct g_class *mp)
}
void
g_confdot(void *p)
g_confdot(void *p, int flag __unused)
{
struct g_class *mp;
struct sbuf *sb;
@ -143,7 +143,7 @@ g_conftxt_class(struct sbuf *sb, struct g_class *mp)
}
void
g_conftxt(void *p)
g_conftxt(void *p, int flag __unused)
{
struct g_class *mp;
struct sbuf *sb;
@ -263,7 +263,7 @@ g_conf_specific(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g
}
void
g_confxml(void *p)
g_confxml(void *p, int flag __unused)
{
g_topology_assert();

View File

@ -55,6 +55,7 @@
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/eventhandler.h>
#include <machine/stdarg.h>
#endif
#include <sys/errno.h>
#include <sys/time.h>
@ -158,28 +159,25 @@ g_do_event(struct g_event *ep)
struct g_provider *pp;
int i;
g_trace(G_T_TOPOLOGY, "g_do_event(%p) %d m:%p g:%p p:%p c:%p - ",
ep, ep->event, ep->class, ep->geom, ep->provider, ep->consumer);
g_trace(G_T_TOPOLOGY, "g_do_event(%p) %d - ", ep, ep->event);
g_topology_assert();
switch (ep->event) {
case EV_CALL_ME:
ep->func(ep->arg);
ep->func(ep->arg, 0);
g_topology_assert();
break;
case EV_NEW_CLASS:
mp2 = ep->class;
if (g_shutdown)
break;
mp2 = ep->ref[0];
if (mp2->taste == NULL)
break;
if (g_shutdown)
break;
LIST_FOREACH(mp, &g_classes, class) {
if (mp2 == mp)
continue;
LIST_FOREACH(gp, &mp->geom, geom) {
LIST_FOREACH(pp, &gp->provider, provider) {
mp2->taste(ep->class, pp, 0);
mp2->taste(mp2, pp, 0);
g_topology_assert();
}
}
@ -188,28 +186,26 @@ g_do_event(struct g_event *ep)
case EV_NEW_PROVIDER:
if (g_shutdown)
break;
g_trace(G_T_TOPOLOGY, "EV_NEW_PROVIDER(%s)",
ep->provider->name);
pp = ep->ref[0];
g_trace(G_T_TOPOLOGY, "EV_NEW_PROVIDER(%s)", pp->name);
LIST_FOREACH(mp, &g_classes, class) {
if (mp->taste == NULL)
continue;
if (!strcmp(ep->provider->name, "geom.ctl") &&
strcmp(mp->name, "DEV"))
continue;
i = 1;
LIST_FOREACH(cp, &ep->provider->consumers, consumers)
LIST_FOREACH(cp, &pp->consumers, consumers)
if(cp->geom->class == mp)
i = 0;
if (i) {
mp->taste(mp, ep->provider, 0);
mp->taste(mp, pp, 0);
g_topology_assert();
}
}
break;
case EV_SPOILED:
pp = ep->ref[0];
g_trace(G_T_TOPOLOGY, "EV_SPOILED(%p(%s),%p)",
ep->provider, ep->provider->name, ep->consumer);
cp = LIST_FIRST(&ep->provider->consumers);
pp, pp->name, ep->ref[1]);
cp = LIST_FIRST(&pp->consumers);
while (cp != NULL) {
cp2 = LIST_NEXT(cp, consumers);
if (cp->spoiled) {
@ -257,14 +253,6 @@ one_event(void)
}
TAILQ_REMOVE(&g_events, ep, events);
mtx_unlock(&g_eventlock);
if (ep->class != NULL)
ep->class->event = NULL;
if (ep->geom != NULL)
ep->geom->event = NULL;
if (ep->provider != NULL)
ep->provider->event = NULL;
if (ep->consumer != NULL)
ep->consumer->event = NULL;
g_do_event(ep);
g_destroy_event(ep);
g_pending_events--;
@ -284,39 +272,27 @@ g_run_events()
}
void
g_post_event(enum g_events ev, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
g_post_event(enum g_events ev, ...)
{
struct g_event *ep;
va_list ap;
void *p;
int n;
g_trace(G_T_TOPOLOGY, "g_post_event(%d, %p, %p, %p, %p)",
ev, mp, gp, pp, cp);
g_trace(G_T_TOPOLOGY, "g_post_event(%d)", ev);
g_topology_assert();
ep = g_malloc(sizeof *ep, M_WAITOK | M_ZERO);
ep->event = ev;
if (mp != NULL) {
ep->class = mp;
KASSERT(mp->event == NULL, ("Double event on class %d %d",
ep->event, mp->event->event));
mp->event = ep;
}
if (gp != NULL) {
ep->geom = gp;
KASSERT(gp->event == NULL, ("Double event on geom %d %d",
ep->event, gp->event->event));
gp->event = ep;
}
if (pp != NULL) {
ep->provider = pp;
KASSERT(pp->event == NULL, ("Double event on provider %s %d %d",
pp->name, ep->event, pp->event->event));
pp->event = ep;
}
if (cp != NULL) {
ep->consumer = cp;
KASSERT(cp->event == NULL, ("Double event on consumer %d %d",
ep->event, cp->event->event));
cp->event = ep;
va_start(ap, ev);
for (n = 0; n < G_N_EVENTREFS; n++) {
p = va_arg(ap, void *);
if (p == NULL)
break;
g_trace(G_T_TOPOLOGY, " ref %p", p);
ep->ref[n++] = p;
}
va_end(ap);
KASSERT(p == NULL, ("Too many references to event"));
mtx_lock(&g_eventlock);
g_pending_events++;
TAILQ_INSERT_TAIL(&g_events, ep, events);
@ -325,36 +301,49 @@ g_post_event(enum g_events ev, struct g_class *mp, struct g_geom *gp, struct g_p
}
void
g_cancel_event(struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
g_cancel_event(void *ref)
{
struct g_event *ep, *epn;
u_int n;
mtx_lock(&g_eventlock);
ep = TAILQ_FIRST(&g_events);
for (;ep != NULL;) {
for (ep = TAILQ_FIRST(&g_events); ep != NULL; ep = epn) {
epn = TAILQ_NEXT(ep, events);
if (
(ep->class != NULL && ep->class == mp) ||
(ep->geom != NULL && ep->geom == gp) ||
(ep->provider != NULL && ep->provider == pp) ||
(ep->consumer != NULL && ep->consumer == cp)) {
TAILQ_REMOVE(&g_events, ep, events);
g_free(ep);
for (n = 0; n < G_N_EVENTREFS; n++) {
if (ep->ref[n] == NULL)
break;
if (ep->ref[n] == ref) {
TAILQ_REMOVE(&g_events, ep, events);
g_free(ep);
break;
}
}
ep = epn;
}
mtx_unlock(&g_eventlock);
}
int
g_call_me(g_call_me_t *func, void *arg)
g_call_me(g_call_me_t *func, void *arg, ...)
{
struct g_event *ep;
va_list ap;
void *p;
u_int n;
g_trace(G_T_TOPOLOGY, "g_call_me(%p, %p", func, arg);
ep = g_malloc(sizeof *ep, M_NOWAIT | M_ZERO);
if (ep == NULL)
return (ENOMEM);
va_start(ap, arg);
for (n = 0; n < G_N_EVENTREFS; n++) {
p = va_arg(ap, void *);
if (p == NULL)
break;
g_trace(G_T_TOPOLOGY, " ref %p", p);
ep->ref[n++] = p;
}
va_end(ap);
KASSERT(p == NULL, ("Too many references to event"));
ep->event = EV_CALL_ME;
ep->func = func;
ep->arg = arg;

View File

@ -66,15 +66,14 @@ enum g_events {
EV_LAST
};
#define G_N_EVENTREFS 20
struct g_event {
enum g_events event;
TAILQ_ENTRY(g_event) events;
struct g_class *class;
struct g_geom *geom;
struct g_provider *provider;
struct g_consumer *consumer;
void *arg;
g_call_me_t *func;
void *ref[G_N_EVENTREFS];
};
/*
@ -86,15 +85,15 @@ struct g_event {
#define GEOM_MINOR_PROVIDERS 10
/* geom_dump.c */
void g_confxml(void *);
void g_confxml(void *, int flag);
void g_conf_specific(struct sbuf *sb, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp);
void g_confdot(void *);
void g_conftxt(void *);
void g_confdot(void *, int flag);
void g_conftxt(void *, int flag);
/* geom_event.c */
void g_event_init(void);
void g_post_event(enum g_events ev, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp);
void g_cancel_event(struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp);
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

@ -161,7 +161,7 @@ sysctl_kern_geom_conftxt(SYSCTL_HANDLER_ARGS)
sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
sbuf_clear(sb);
g_call_me(g_conftxt, sb);
g_call_me(g_conftxt, sb, NULL);
do {
tsleep(sb, PZERO, "g_conftxt", hz);
} while(!sbuf_done(sb));
@ -178,7 +178,7 @@ sysctl_kern_geom_confdot(SYSCTL_HANDLER_ARGS)
sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
sbuf_clear(sb);
g_call_me(g_confdot, sb);
g_call_me(g_confdot, sb, NULL);
do {
tsleep(sb, PZERO, "g_confdot", hz);
} while(!sbuf_done(sb));
@ -195,7 +195,7 @@ sysctl_kern_geom_confxml(SYSCTL_HANDLER_ARGS)
sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
sbuf_clear(sb);
g_call_me(g_confxml, sb);
g_call_me(g_confxml, sb, NULL);
do {
tsleep(sb, PZERO, "g_confxml", hz);
} while(!sbuf_done(sb));

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)
g_mbr_ioctl(void *arg, int flag __unused)
{
struct bio *bp;
struct g_geom *gp;
@ -249,7 +249,7 @@ g_mbr_start(struct bio *bp)
* some I/O requests. Ask the event-handler to schedule
* us in a less restricted environment.
*/
error = g_call_me(g_mbr_ioctl, bp);
error = g_call_me(g_mbr_ioctl, bp, gp, NULL);
if (error)
g_io_deliver(bp, error);
/*

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)
g_pc98_ioctl(void *arg, int flag __unused)
{
struct bio *bp;
struct g_geom *gp;
@ -234,7 +234,7 @@ g_pc98_start(struct bio *bp)
* some I/O requests. Ask the event-handler to schedule
* us in a less restricted environment.
*/
error = g_call_me(g_pc98_ioctl, bp);
error = g_call_me(g_pc98_ioctl, bp, gp, NULL);
if (error)
g_io_deliver(bp, error);
/*

View File

@ -83,7 +83,7 @@ g_add_class(struct g_class *mp)
LIST_INIT(&mp->geom);
LIST_INSERT_HEAD(&g_classes, mp, class);
if (g_nproviders > 0)
g_post_event(EV_NEW_CLASS, mp, NULL, NULL, NULL);
g_post_event(EV_NEW_CLASS, mp, NULL);
g_topology_unlock();
}
@ -126,7 +126,7 @@ g_destroy_geom(struct g_geom *gp)
KASSERT(LIST_EMPTY(&gp->provider),
("g_destroy_geom(%s) with provider(s) [%p]",
gp->name, LIST_FIRST(&gp->consumer)));
g_cancel_event(NULL, gp, NULL, NULL);
g_cancel_event(gp);
LIST_REMOVE(gp, geom);
TAILQ_REMOVE(&geoms, gp, geoms);
g_free(gp->name);
@ -163,7 +163,7 @@ g_destroy_consumer(struct g_consumer *cp)
KASSERT (cp->acr == 0, ("g_destroy_consumer with acr"));
KASSERT (cp->acw == 0, ("g_destroy_consumer with acw"));
KASSERT (cp->ace == 0, ("g_destroy_consumer with ace"));
g_cancel_event(NULL, NULL, NULL, cp);
g_cancel_event(cp);
LIST_REMOVE(cp, consumer);
devstat_remove_entry(cp->stat);
g_free(cp);
@ -193,7 +193,7 @@ g_new_providerf(struct g_geom *gp, const char *fmt, ...)
DEVSTAT_TYPE_DIRECT, DEVSTAT_PRIORITY_MAX);
LIST_INSERT_HEAD(&gp->provider, pp, provider);
g_nproviders++;
g_post_event(EV_NEW_PROVIDER, NULL, NULL, pp, NULL);
g_post_event(EV_NEW_PROVIDER, pp, NULL);
return (pp);
}
@ -218,7 +218,7 @@ g_destroy_provider(struct g_provider *pp)
KASSERT (pp->acr == 0, ("g_destroy_provider with acr"));
KASSERT (pp->acw == 0, ("g_destroy_provider with acw"));
KASSERT (pp->acw == 0, ("g_destroy_provider with ace"));
g_cancel_event(NULL, NULL, pp, NULL);
g_cancel_event(pp);
g_nproviders--;
LIST_REMOVE(pp, provider);
gp = pp->geom;
@ -447,7 +447,7 @@ g_access_rel(struct g_consumer *cp, int dcr, int dcw, int dce)
g_spoil(pp, cp);
else if (pp->acw != 0 && pp->acw == -dcw &&
!(pp->geom->flags & G_GEOM_WITHER))
g_post_event(EV_NEW_PROVIDER, NULL, NULL, pp, NULL);
g_post_event(EV_NEW_PROVIDER, pp, NULL);
pp->acr += dcr;
pp->acw += dcw;
@ -567,7 +567,7 @@ g_spoil(struct g_provider *pp, struct g_consumer *cp)
KASSERT(cp2->ace == 0, ("spoiling cp->ace = %d", cp2->ace));
cp2->spoiled++;
}
g_post_event(EV_SPOILED, NULL, NULL, pp, cp);
g_post_event(EV_SPOILED, pp, cp, NULL);
}
int