geom_event.c (e805e8f0e8f9f762bfb5bffd72380a1b101b1a8b) geom_event.c (b1876192f015b1cf392b52b82b124265fc9683a7)
1/*-
2 * Copyright (c) 2002 Poul-Henning Kamp
3 * Copyright (c) 2002 Networks Associates Technology, Inc.
4 * All rights reserved.
5 *
6 * This software was developed for the FreeBSD Project by Poul-Henning Kamp
7 * and NAI Labs, the Security Research Division of Network Associates, Inc.
8 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the

--- 44 unchanged lines hidden (view full) ---

53#include <sys/systm.h>
54#include <sys/kernel.h>
55#include <sys/lock.h>
56#include <sys/mutex.h>
57#endif
58#include <sys/errno.h>
59#include <sys/time.h>
60#include <geom/geom.h>
1/*-
2 * Copyright (c) 2002 Poul-Henning Kamp
3 * Copyright (c) 2002 Networks Associates Technology, Inc.
4 * All rights reserved.
5 *
6 * This software was developed for the FreeBSD Project by Poul-Henning Kamp
7 * and NAI Labs, the Security Research Division of Network Associates, Inc.
8 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the

--- 44 unchanged lines hidden (view full) ---

53#include <sys/systm.h>
54#include <sys/kernel.h>
55#include <sys/lock.h>
56#include <sys/mutex.h>
57#endif
58#include <sys/errno.h>
59#include <sys/time.h>
60#include <geom/geom.h>
61#include <geom/geom_int.h>
61
62static struct event_tailq_head g_events = TAILQ_HEAD_INITIALIZER(g_events);
63static u_int g_pending_events, g_silence_events;
62
63static struct event_tailq_head g_events = TAILQ_HEAD_INITIALIZER(g_events);
64static u_int g_pending_events, g_silence_events;
64static void g_do_event(struct g_event *ep, struct thread *tp);
65static void g_do_event(struct g_event *ep);
65static TAILQ_HEAD(,g_provider) g_doorstep = TAILQ_HEAD_INITIALIZER(g_doorstep);
66static struct mtx g_doorlock;
67
68void
69g_silence(void)
70{
71
72 g_silence_events = 1;

--- 30 unchanged lines hidden (view full) ---

103}
104
105/*
106 * This function is called once on each provider which the event handler
107 * finds on its g_doorstep.
108 */
109
110static void
66static TAILQ_HEAD(,g_provider) g_doorstep = TAILQ_HEAD_INITIALIZER(g_doorstep);
67static struct mtx g_doorlock;
68
69void
70g_silence(void)
71{
72
73 g_silence_events = 1;

--- 30 unchanged lines hidden (view full) ---

104}
105
106/*
107 * This function is called once on each provider which the event handler
108 * finds on its g_doorstep.
109 */
110
111static void
111g_orphan_register(struct g_provider *pp, struct thread *tp)
112g_orphan_register(struct g_provider *pp)
112{
113 struct g_consumer *cp, *cp2;
114
115 g_trace(G_T_TOPOLOGY, "g_orphan_register(%s)", pp->name);
116 g_topology_assert();
117
118 /*
119 * Tell all consumers the bad news.
120 * Don't get surprised if they self-destruct.
121 */
122 cp = LIST_FIRST(&pp->consumers);
123 while (cp != NULL) {
124 cp2 = LIST_NEXT(cp, consumers);
125 KASSERT(cp->geom->class->orphan != NULL,
126 ("class %s has no orphan, geom %s",
127 cp->geom->class->name, cp->geom->name));
113{
114 struct g_consumer *cp, *cp2;
115
116 g_trace(G_T_TOPOLOGY, "g_orphan_register(%s)", pp->name);
117 g_topology_assert();
118
119 /*
120 * Tell all consumers the bad news.
121 * Don't get surprised if they self-destruct.
122 */
123 cp = LIST_FIRST(&pp->consumers);
124 while (cp != NULL) {
125 cp2 = LIST_NEXT(cp, consumers);
126 KASSERT(cp->geom->class->orphan != NULL,
127 ("class %s has no orphan, geom %s",
128 cp->geom->class->name, cp->geom->name));
128 cp->geom->class->orphan(cp, tp);
129 cp->geom->class->orphan(cp);
129 cp = cp2;
130 }
131}
132
133static void
134g_destroy_event(struct g_event *ep)
135{
136
137 g_free(ep);
138}
139
140static void
130 cp = cp2;
131 }
132}
133
134static void
135g_destroy_event(struct g_event *ep)
136{
137
138 g_free(ep);
139}
140
141static void
141g_do_event(struct g_event *ep, struct thread *tp)
142g_do_event(struct g_event *ep)
142{
143 struct g_class *mp, *mp2;
144 struct g_geom *gp;
145 struct g_consumer *cp, *cp2;
146 struct g_provider *pp;
147 int i;
148
149 g_trace(G_T_TOPOLOGY, "g_do_event(%p) %d m:%p g:%p p:%p c:%p - ",

--- 4 unchanged lines hidden (view full) ---

154 mp2 = ep->class;
155 if (mp2->taste == NULL)
156 break;
157 LIST_FOREACH(mp, &g_classs, class) {
158 if (mp2 == mp)
159 continue;
160 LIST_FOREACH(gp, &mp->geom, geom) {
161 LIST_FOREACH(pp, &gp->provider, provider) {
143{
144 struct g_class *mp, *mp2;
145 struct g_geom *gp;
146 struct g_consumer *cp, *cp2;
147 struct g_provider *pp;
148 int i;
149
150 g_trace(G_T_TOPOLOGY, "g_do_event(%p) %d m:%p g:%p p:%p c:%p - ",

--- 4 unchanged lines hidden (view full) ---

155 mp2 = ep->class;
156 if (mp2->taste == NULL)
157 break;
158 LIST_FOREACH(mp, &g_classs, class) {
159 if (mp2 == mp)
160 continue;
161 LIST_FOREACH(gp, &mp->geom, geom) {
162 LIST_FOREACH(pp, &gp->provider, provider) {
162 mp2->taste(ep->class, pp, tp, 0);
163 mp2->taste(ep->class, pp, 0);
163 g_topology_assert();
164 }
165 }
166 }
167 break;
168 case EV_NEW_PROVIDER:
169 g_trace(G_T_TOPOLOGY, "EV_NEW_PROVIDER(%s)",
170 ep->provider->name);
171 LIST_FOREACH(mp, &g_classs, class) {
172 if (mp->taste == NULL)
173 continue;
174 i = 1;
175 LIST_FOREACH(cp, &ep->provider->consumers, consumers)
176 if(cp->geom->class == mp)
177 i = 0;
178 if (i) {
164 g_topology_assert();
165 }
166 }
167 }
168 break;
169 case EV_NEW_PROVIDER:
170 g_trace(G_T_TOPOLOGY, "EV_NEW_PROVIDER(%s)",
171 ep->provider->name);
172 LIST_FOREACH(mp, &g_classs, class) {
173 if (mp->taste == NULL)
174 continue;
175 i = 1;
176 LIST_FOREACH(cp, &ep->provider->consumers, consumers)
177 if(cp->geom->class == mp)
178 i = 0;
179 if (i) {
179 mp->taste(mp, ep->provider, tp, 0);
180 mp->taste(mp, ep->provider, 0);
180 g_topology_assert();
181 }
182 }
183 break;
184 case EV_SPOILED:
185 g_trace(G_T_TOPOLOGY, "EV_SPOILED(%p(%s),%p)",
186 ep->provider, ep->provider->name, ep->consumer);
187 cp = LIST_FIRST(&ep->provider->consumers);

--- 11 unchanged lines hidden (view full) ---

199 break;
200 case EV_LAST:
201 default:
202 KASSERT(1 == 0, ("Unknown event %d", ep->event));
203 }
204}
205
206static int
181 g_topology_assert();
182 }
183 }
184 break;
185 case EV_SPOILED:
186 g_trace(G_T_TOPOLOGY, "EV_SPOILED(%p(%s),%p)",
187 ep->provider, ep->provider->name, ep->consumer);
188 cp = LIST_FIRST(&ep->provider->consumers);

--- 11 unchanged lines hidden (view full) ---

200 break;
201 case EV_LAST:
202 default:
203 KASSERT(1 == 0, ("Unknown event %d", ep->event));
204 }
205}
206
207static int
207one_event(struct thread *tp)
208one_event(void)
208{
209 struct g_event *ep;
210 struct g_provider *pp;
211
212 g_topology_lock();
213 for (;;) {
214 mtx_lock(&g_doorlock);
215 pp = TAILQ_FIRST(&g_doorstep);
216 if (pp != NULL)
217 TAILQ_REMOVE(&g_doorstep, pp, orphan);
218 mtx_unlock(&g_doorlock);
219 if (pp == NULL)
220 break;
209{
210 struct g_event *ep;
211 struct g_provider *pp;
212
213 g_topology_lock();
214 for (;;) {
215 mtx_lock(&g_doorlock);
216 pp = TAILQ_FIRST(&g_doorstep);
217 if (pp != NULL)
218 TAILQ_REMOVE(&g_doorstep, pp, orphan);
219 mtx_unlock(&g_doorlock);
220 if (pp == NULL)
221 break;
221 g_orphan_register(pp, tp);
222 g_orphan_register(pp);
222 }
223 ep = TAILQ_FIRST(&g_events);
224 if (ep == NULL) {
225 g_topology_unlock();
226 return (0);
227 }
228 TAILQ_REMOVE(&g_events, ep, events);
229 if (ep->class != NULL)
230 ep->class->event = NULL;
231 if (ep->geom != NULL)
232 ep->geom->event = NULL;
233 if (ep->provider != NULL)
234 ep->provider->event = NULL;
235 if (ep->consumer != NULL)
236 ep->consumer->event = NULL;
223 }
224 ep = TAILQ_FIRST(&g_events);
225 if (ep == NULL) {
226 g_topology_unlock();
227 return (0);
228 }
229 TAILQ_REMOVE(&g_events, ep, events);
230 if (ep->class != NULL)
231 ep->class->event = NULL;
232 if (ep->geom != NULL)
233 ep->geom->event = NULL;
234 if (ep->provider != NULL)
235 ep->provider->event = NULL;
236 if (ep->consumer != NULL)
237 ep->consumer->event = NULL;
237 g_do_event(ep, tp);
238 g_do_event(ep);
238 g_pending_events--;
239 if (g_pending_events == 0) {
240 mtx_lock(&Giant);
241 wakeup(&g_pending_events);
242 mtx_unlock(&Giant);
243 }
244 g_topology_unlock();
245 g_destroy_event(ep);
246 return (1);
247}
248
249void
239 g_pending_events--;
240 if (g_pending_events == 0) {
241 mtx_lock(&Giant);
242 wakeup(&g_pending_events);
243 mtx_unlock(&Giant);
244 }
245 g_topology_unlock();
246 g_destroy_event(ep);
247 return (1);
248}
249
250void
250g_run_events(struct thread *tp)
251g_run_events()
251{
252
252{
253
253 while (one_event(tp))
254 while (one_event())
254 ;
255}
256
257void
258g_post_event(enum g_events ev, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
259{
260 struct g_event *ep;
261

--- 38 unchanged lines hidden ---
255 ;
256}
257
258void
259g_post_event(enum g_events ev, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp)
260{
261 struct g_event *ep;
262

--- 38 unchanged lines hidden ---