summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2003-04-02 20:41:18 +0000
committerphk <phk@FreeBSD.org>2003-04-02 20:41:18 +0000
commitcedf04c4758318e15e1a5924e4226bb5a9699107 (patch)
treebb0413612f4b063a82d75d5551149f4526dbc56d /sys
parent021eeb20207634119a2920f756b6eba04148bbf9 (diff)
downloadFreeBSD-src-cedf04c4758318e15e1a5924e4226bb5a9699107.zip
FreeBSD-src-cedf04c4758318e15e1a5924e4226bb5a9699107.tar.gz
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.
Diffstat (limited to 'sys')
-rw-r--r--sys/geom/geom.h4
-rw-r--r--sys/geom/geom_bsd.c8
-rw-r--r--sys/geom/geom_disk.c8
-rw-r--r--sys/geom/geom_disk.h4
-rw-r--r--sys/geom/geom_dump.c6
-rw-r--r--sys/geom/geom_event.c113
-rw-r--r--sys/geom/geom_int.h17
-rw-r--r--sys/geom/geom_kern.c6
-rw-r--r--sys/geom/geom_mbr.c4
-rw-r--r--sys/geom/geom_pc98.c4
-rw-r--r--sys/geom/geom_subr.c14
11 files changed, 90 insertions, 98 deletions
diff --git a/sys/geom/geom.h b/sys/geom/geom.h
index cd1691c..55a1172 100644
--- a/sys/geom/geom.h
+++ b/sys/geom/geom.h
@@ -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);
diff --git a/sys/geom/geom_bsd.c b/sys/geom/geom_bsd.c
index 6e14333..39f4222 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)
+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);
/*
diff --git a/sys/geom/geom_disk.c b/sys/geom/geom_disk.c
index 7d5b677..7ffd464 100644
--- a/sys/geom/geom_disk.c
+++ b/sys/geom/geom_disk.c
@@ -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);
}
diff --git a/sys/geom/geom_disk.h b/sys/geom/geom_disk.h
index 7cd079e..712e871 100644
--- a/sys/geom/geom_disk.h
+++ b/sys/geom/geom_disk.h
@@ -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;
diff --git a/sys/geom/geom_dump.c b/sys/geom/geom_dump.c
index b1ea85b..1c39fc2 100644
--- a/sys/geom/geom_dump.c
+++ b/sys/geom/geom_dump.c
@@ -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();
diff --git a/sys/geom/geom_event.c b/sys/geom/geom_event.c
index 0af148f..e0e6deb 100644
--- a/sys/geom/geom_event.c
+++ b/sys/geom/geom_event.c
@@ -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;
diff --git a/sys/geom/geom_int.h b/sys/geom/geom_int.h
index f709d73..aa8877d 100644
--- a/sys/geom/geom_int.h
+++ b/sys/geom/geom_int.h
@@ -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);
diff --git a/sys/geom/geom_kern.c b/sys/geom/geom_kern.c
index 227c6d0..0c2029d 100644
--- a/sys/geom/geom_kern.c
+++ b/sys/geom/geom_kern.c
@@ -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));
diff --git a/sys/geom/geom_mbr.c b/sys/geom/geom_mbr.c
index b60bc22..5b24938 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)
+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);
/*
diff --git a/sys/geom/geom_pc98.c b/sys/geom/geom_pc98.c
index 443d923..390ac95 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)
+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);
/*
diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c
index f2c43fe..9a54da1 100644
--- a/sys/geom/geom_subr.c
+++ b/sys/geom/geom_subr.c
@@ -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
OpenPOWER on IntegriCloud