geom_subr.c (b07ef6c2db5f1daa76d9813e09b53d98ec9b288f) geom_subr.c (3d1d5bc3c36007d92f05fc5b1d08998598722a0b)
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

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

52#include <geom/geom.h>
53#include <geom/geom_int.h>
54#include <machine/stdarg.h>
55
56struct class_list_head g_classes = LIST_HEAD_INITIALIZER(g_classes);
57static struct g_tailq_head geoms = TAILQ_HEAD_INITIALIZER(geoms);
58char *g_wait_event, *g_wait_up, *g_wait_down, *g_wait_sim;
59
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

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

52#include <geom/geom.h>
53#include <geom/geom_int.h>
54#include <machine/stdarg.h>
55
56struct class_list_head g_classes = LIST_HEAD_INITIALIZER(g_classes);
57static struct g_tailq_head geoms = TAILQ_HEAD_INITIALIZER(geoms);
58char *g_wait_event, *g_wait_up, *g_wait_down, *g_wait_sim;
59
60static int g_valid_obj(void const *ptr);
61
62struct g_hh00 {
63 struct g_class *mp;
64 int error;
65};
66
67/*
68 * This event offers a new class a chance to taste all preexisting providers.
69 */

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

120 struct g_geom *gp;
121 struct g_provider *pp;
122 struct g_consumer *cp;
123 int error;
124
125 g_topology_assert();
126 hh = arg;
127 mp = hh->mp;
60struct g_hh00 {
61 struct g_class *mp;
62 int error;
63};
64
65/*
66 * This event offers a new class a chance to taste all preexisting providers.
67 */

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

118 struct g_geom *gp;
119 struct g_provider *pp;
120 struct g_consumer *cp;
121 int error;
122
123 g_topology_assert();
124 hh = arg;
125 mp = hh->mp;
126 G_VALID_CLASS(mp);
128 g_trace(G_T_TOPOLOGY, "g_unload_class(%s)", mp->name);
129
130 /*
131 * We allow unloading if we have no geoms, or a class
132 * method we can use to get rid of them.
133 */
134 if (!LIST_EMPTY(&mp->geom) && mp->destroy_geom == NULL) {
135 hh->error = EOPNOTSUPP;

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

211struct g_geom *
212g_new_geomf(struct g_class *mp, const char *fmt, ...)
213{
214 struct g_geom *gp;
215 va_list ap;
216 struct sbuf *sb;
217
218 g_topology_assert();
127 g_trace(G_T_TOPOLOGY, "g_unload_class(%s)", mp->name);
128
129 /*
130 * We allow unloading if we have no geoms, or a class
131 * method we can use to get rid of them.
132 */
133 if (!LIST_EMPTY(&mp->geom) && mp->destroy_geom == NULL) {
134 hh->error = EOPNOTSUPP;

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

210struct g_geom *
211g_new_geomf(struct g_class *mp, const char *fmt, ...)
212{
213 struct g_geom *gp;
214 va_list ap;
215 struct sbuf *sb;
216
217 g_topology_assert();
219 KASSERT(g_valid_obj(mp), ("g_new_geom_f() on alien class %p", mp));
218 G_VALID_CLASS(mp);
220 sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
221 va_start(ap, fmt);
222 sbuf_vprintf(sb, fmt, ap);
223 va_end(ap);
224 sbuf_finish(sb);
225 gp = g_malloc(sizeof *gp, M_WAITOK | M_ZERO);
226 gp->name = g_malloc(sbuf_len(sb) + 1, M_WAITOK | M_ZERO);
227 gp->class = mp;

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

234 sbuf_delete(sb);
235 return (gp);
236}
237
238void
239g_destroy_geom(struct g_geom *gp)
240{
241
219 sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
220 va_start(ap, fmt);
221 sbuf_vprintf(sb, fmt, ap);
222 va_end(ap);
223 sbuf_finish(sb);
224 gp = g_malloc(sizeof *gp, M_WAITOK | M_ZERO);
225 gp->name = g_malloc(sbuf_len(sb) + 1, M_WAITOK | M_ZERO);
226 gp->class = mp;

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

233 sbuf_delete(sb);
234 return (gp);
235}
236
237void
238g_destroy_geom(struct g_geom *gp)
239{
240
242 g_trace(G_T_TOPOLOGY, "g_destroy_geom(%p(%s))", gp, gp->name);
243 g_topology_assert();
241 g_topology_assert();
242 G_VALID_GEOM(gp);
243 g_trace(G_T_TOPOLOGY, "g_destroy_geom(%p(%s))", gp, gp->name);
244 KASSERT(LIST_EMPTY(&gp->consumer),
245 ("g_destroy_geom(%s) with consumer(s) [%p]",
246 gp->name, LIST_FIRST(&gp->consumer)));
247 KASSERT(LIST_EMPTY(&gp->provider),
248 ("g_destroy_geom(%s) with provider(s) [%p]",
249 gp->name, LIST_FIRST(&gp->provider)));
250 g_cancel_event(gp);
251 LIST_REMOVE(gp, geom);
252 TAILQ_REMOVE(&geoms, gp, geoms);
253 g_free(gp->name);
254 g_free(gp);
255}
256
257/*
244 KASSERT(LIST_EMPTY(&gp->consumer),
245 ("g_destroy_geom(%s) with consumer(s) [%p]",
246 gp->name, LIST_FIRST(&gp->consumer)));
247 KASSERT(LIST_EMPTY(&gp->provider),
248 ("g_destroy_geom(%s) with provider(s) [%p]",
249 gp->name, LIST_FIRST(&gp->provider)));
250 g_cancel_event(gp);
251 LIST_REMOVE(gp, geom);
252 TAILQ_REMOVE(&geoms, gp, geoms);
253 g_free(gp->name);
254 g_free(gp);
255}
256
257/*
258 * This function is called (repeatedly) until has withered away.
258 * This function is called (repeatedly) until the has withered away.
259 */
260void
261g_wither_geom(struct g_geom *gp, int error)
262{
263 struct g_provider *pp, *pp2;
264 struct g_consumer *cp, *cp2;
265 static int once_is_enough;
266
259 */
260void
261g_wither_geom(struct g_geom *gp, int error)
262{
263 struct g_provider *pp, *pp2;
264 struct g_consumer *cp, *cp2;
265 static int once_is_enough;
266
267 g_topology_assert();
268 G_VALID_GEOM(gp);
267 if (once_is_enough)
268 return;
269 once_is_enough = 1;
270 g_trace(G_T_TOPOLOGY, "g_wither_geom(%p(%s))", gp, gp->name);
269 if (once_is_enough)
270 return;
271 once_is_enough = 1;
272 g_trace(G_T_TOPOLOGY, "g_wither_geom(%p(%s))", gp, gp->name);
271 g_topology_assert();
272 if (!(gp->flags & G_GEOM_WITHER)) {
273 gp->flags |= G_GEOM_WITHER;
274 LIST_FOREACH(pp, &gp->provider, provider)
275 if (!(pp->flags & G_PF_ORPHAN))
276 g_orphan_provider(pp, error);
277 }
278 for (pp = LIST_FIRST(&gp->provider); pp != NULL; pp = pp2) {
279 pp2 = LIST_NEXT(pp, provider);

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

294}
295
296struct g_consumer *
297g_new_consumer(struct g_geom *gp)
298{
299 struct g_consumer *cp;
300
301 g_topology_assert();
273 if (!(gp->flags & G_GEOM_WITHER)) {
274 gp->flags |= G_GEOM_WITHER;
275 LIST_FOREACH(pp, &gp->provider, provider)
276 if (!(pp->flags & G_PF_ORPHAN))
277 g_orphan_provider(pp, error);
278 }
279 for (pp = LIST_FIRST(&gp->provider); pp != NULL; pp = pp2) {
280 pp2 = LIST_NEXT(pp, provider);

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

295}
296
297struct g_consumer *
298g_new_consumer(struct g_geom *gp)
299{
300 struct g_consumer *cp;
301
302 g_topology_assert();
303 G_VALID_GEOM(gp);
302 KASSERT(!(gp->flags & G_GEOM_WITHER),
303 ("g_new_consumer on WITHERing geom(%s) (class %s)",
304 gp->name, gp->class->name));
305 KASSERT(gp->orphan != NULL,
306 ("g_new_consumer on geom(%s) (class %s) without orphan",
307 gp->name, gp->class->name));
308
309 cp = g_malloc(sizeof *cp, M_WAITOK | M_ZERO);

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

314 return(cp);
315}
316
317void
318g_destroy_consumer(struct g_consumer *cp)
319{
320 struct g_geom *gp;
321
304 KASSERT(!(gp->flags & G_GEOM_WITHER),
305 ("g_new_consumer on WITHERing geom(%s) (class %s)",
306 gp->name, gp->class->name));
307 KASSERT(gp->orphan != NULL,
308 ("g_new_consumer on geom(%s) (class %s) without orphan",
309 gp->name, gp->class->name));
310
311 cp = g_malloc(sizeof *cp, M_WAITOK | M_ZERO);

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

316 return(cp);
317}
318
319void
320g_destroy_consumer(struct g_consumer *cp)
321{
322 struct g_geom *gp;
323
322 g_trace(G_T_TOPOLOGY, "g_destroy_consumer(%p)", cp);
323 g_topology_assert();
324 g_topology_assert();
325 G_VALID_CONSUMER(cp);
326 g_trace(G_T_TOPOLOGY, "g_destroy_consumer(%p)", cp);
324 KASSERT (cp->provider == NULL, ("g_destroy_consumer but attached"));
325 KASSERT (cp->acr == 0, ("g_destroy_consumer with acr"));
326 KASSERT (cp->acw == 0, ("g_destroy_consumer with acw"));
327 KASSERT (cp->ace == 0, ("g_destroy_consumer with ace"));
328 g_cancel_event(cp);
329 gp = cp->geom;
330 LIST_REMOVE(cp, consumer);
331 devstat_remove_entry(cp->stat);

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

343 int i;
344
345 g_topology_assert();
346 if (flag == EV_CANCEL)
347 return;
348 if (g_shutdown)
349 return;
350 pp = arg;
327 KASSERT (cp->provider == NULL, ("g_destroy_consumer but attached"));
328 KASSERT (cp->acr == 0, ("g_destroy_consumer with acr"));
329 KASSERT (cp->acw == 0, ("g_destroy_consumer with acw"));
330 KASSERT (cp->ace == 0, ("g_destroy_consumer with ace"));
331 g_cancel_event(cp);
332 gp = cp->geom;
333 LIST_REMOVE(cp, consumer);
334 devstat_remove_entry(cp->stat);

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

346 int i;
347
348 g_topology_assert();
349 if (flag == EV_CANCEL)
350 return;
351 if (g_shutdown)
352 return;
353 pp = arg;
354 G_VALID_PROVIDER(pp);
351 LIST_FOREACH(mp, &g_classes, class) {
352 if (mp->taste == NULL)
353 continue;
354 i = 1;
355 LIST_FOREACH(cp, &pp->consumers, consumers)
356 if (cp->geom->class == mp)
357 i = 0;
358 if (!i)
359 continue;
360 mp->taste(mp, pp, 0);
361 g_topology_assert();
355 LIST_FOREACH(mp, &g_classes, class) {
356 if (mp->taste == NULL)
357 continue;
358 i = 1;
359 LIST_FOREACH(cp, &pp->consumers, consumers)
360 if (cp->geom->class == mp)
361 i = 0;
362 if (!i)
363 continue;
364 mp->taste(mp, pp, 0);
365 g_topology_assert();
362 /*
363 * XXX: Bandaid for 5.2-RELEASE
364 * XXX: DO NOT REPLICATE THIS CODE!
365 */
366 if (!g_valid_obj(pp)) {
367 printf("g_provider %p disappeared while tasting\n", pp);
368 return;
369 }
370 }
371}
372
373
374struct g_provider *
375g_new_providerf(struct g_geom *gp, const char *fmt, ...)
376{
377 struct g_provider *pp;
378 struct sbuf *sb;
379 va_list ap;
380
381 g_topology_assert();
366 }
367}
368
369
370struct g_provider *
371g_new_providerf(struct g_geom *gp, const char *fmt, ...)
372{
373 struct g_provider *pp;
374 struct sbuf *sb;
375 va_list ap;
376
377 g_topology_assert();
378 G_VALID_GEOM(gp);
382 KASSERT(gp->start != NULL,
383 ("new provider on geom(%s) without ->start (class %s)",
384 gp->name, gp->class->name));
385 KASSERT(!(gp->flags & G_GEOM_WITHER),
386 ("new provider on WITHERing geom(%s) (class %s)",
387 gp->name, gp->class->name));
388 sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
389 va_start(ap, fmt);

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

403 g_post_event(g_new_provider_event, pp, M_WAITOK, pp, NULL);
404 return (pp);
405}
406
407void
408g_error_provider(struct g_provider *pp, int error)
409{
410
379 KASSERT(gp->start != NULL,
380 ("new provider on geom(%s) without ->start (class %s)",
381 gp->name, gp->class->name));
382 KASSERT(!(gp->flags & G_GEOM_WITHER),
383 ("new provider on WITHERing geom(%s) (class %s)",
384 gp->name, gp->class->name));
385 sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
386 va_start(ap, fmt);

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

400 g_post_event(g_new_provider_event, pp, M_WAITOK, pp, NULL);
401 return (pp);
402}
403
404void
405g_error_provider(struct g_provider *pp, int error)
406{
407
408 /* G_VALID_PROVIDER(pp); We may not have g_topology */
411 pp->error = error;
412}
413
414struct g_provider *
415g_provider_by_name(char const *arg)
416{
417 struct g_class *cp;
418 struct g_geom *gp;

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

430}
431
432void
433g_destroy_provider(struct g_provider *pp)
434{
435 struct g_geom *gp;
436
437 g_topology_assert();
409 pp->error = error;
410}
411
412struct g_provider *
413g_provider_by_name(char const *arg)
414{
415 struct g_class *cp;
416 struct g_geom *gp;

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

428}
429
430void
431g_destroy_provider(struct g_provider *pp)
432{
433 struct g_geom *gp;
434
435 g_topology_assert();
436 G_VALID_PROVIDER(pp);
438 KASSERT(LIST_EMPTY(&pp->consumers),
439 ("g_destroy_provider but attached"));
440 KASSERT (pp->acr == 0, ("g_destroy_provider with acr"));
441 KASSERT (pp->acw == 0, ("g_destroy_provider with acw"));
442 KASSERT (pp->acw == 0, ("g_destroy_provider with ace"));
443 g_cancel_event(pp);
444 LIST_REMOVE(pp, provider);
445 gp = pp->geom;

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

469static int
470redo_rank(struct g_geom *gp)
471{
472 struct g_consumer *cp;
473 struct g_geom *gp1, *gp2;
474 int n, m;
475
476 g_topology_assert();
437 KASSERT(LIST_EMPTY(&pp->consumers),
438 ("g_destroy_provider but attached"));
439 KASSERT (pp->acr == 0, ("g_destroy_provider with acr"));
440 KASSERT (pp->acw == 0, ("g_destroy_provider with acw"));
441 KASSERT (pp->acw == 0, ("g_destroy_provider with ace"));
442 g_cancel_event(pp);
443 LIST_REMOVE(pp, provider);
444 gp = pp->geom;

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

468static int
469redo_rank(struct g_geom *gp)
470{
471 struct g_consumer *cp;
472 struct g_geom *gp1, *gp2;
473 int n, m;
474
475 g_topology_assert();
476 G_VALID_GEOM(gp);
477
478 /* Invalidate this geoms rank and move it to the tail */
479 gp1 = TAILQ_NEXT(gp, geoms);
480 if (gp1 != NULL) {
481 gp->rank = 0;
482 TAILQ_REMOVE(&geoms, gp, geoms);
483 TAILQ_INSERT_TAIL(&geoms, gp, geoms);
484 } else {

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

518}
519
520int
521g_attach(struct g_consumer *cp, struct g_provider *pp)
522{
523 int error;
524
525 g_topology_assert();
477
478 /* Invalidate this geoms rank and move it to the tail */
479 gp1 = TAILQ_NEXT(gp, geoms);
480 if (gp1 != NULL) {
481 gp->rank = 0;
482 TAILQ_REMOVE(&geoms, gp, geoms);
483 TAILQ_INSERT_TAIL(&geoms, gp, geoms);
484 } else {

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

518}
519
520int
521g_attach(struct g_consumer *cp, struct g_provider *pp)
522{
523 int error;
524
525 g_topology_assert();
526 G_VALID_CONSUMER(cp);
527 G_VALID_PROVIDER(pp);
526 KASSERT(cp->provider == NULL, ("attach but attached"));
527 cp->provider = pp;
528 LIST_INSERT_HEAD(&pp->consumers, cp, consumers);
529 error = redo_rank(cp->geom);
530 if (error) {
531 LIST_REMOVE(cp, consumers);
532 cp->provider = NULL;
533 redo_rank(cp->geom);
534 }
535 return (error);
536}
537
538void
539g_detach(struct g_consumer *cp)
540{
541 struct g_provider *pp;
542
528 KASSERT(cp->provider == NULL, ("attach but attached"));
529 cp->provider = pp;
530 LIST_INSERT_HEAD(&pp->consumers, cp, consumers);
531 error = redo_rank(cp->geom);
532 if (error) {
533 LIST_REMOVE(cp, consumers);
534 cp->provider = NULL;
535 redo_rank(cp->geom);
536 }
537 return (error);
538}
539
540void
541g_detach(struct g_consumer *cp)
542{
543 struct g_provider *pp;
544
543 g_trace(G_T_TOPOLOGY, "g_detach(%p)", cp);
544 KASSERT(cp != (void*)0xd0d0d0d0, ("ARGH!"));
545 g_topology_assert();
545 g_topology_assert();
546 G_VALID_CONSUMER(cp);
547 g_trace(G_T_TOPOLOGY, "g_detach(%p)", cp);
546 KASSERT(cp->provider != NULL, ("detach but not attached"));
547 KASSERT(cp->acr == 0, ("detach but nonzero acr"));
548 KASSERT(cp->acw == 0, ("detach but nonzero acw"));
549 KASSERT(cp->ace == 0, ("detach but nonzero ace"));
550 KASSERT(cp->nstart == cp->nend,
551 ("detach with active requests"));
552 pp = cp->provider;
553 LIST_REMOVE(cp, consumers);

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

568
569int
570g_access(struct g_consumer *cp, int dcr, int dcw, int dce)
571{
572 struct g_provider *pp;
573 int pr,pw,pe;
574 int error;
575
548 KASSERT(cp->provider != NULL, ("detach but not attached"));
549 KASSERT(cp->acr == 0, ("detach but nonzero acr"));
550 KASSERT(cp->acw == 0, ("detach but nonzero acw"));
551 KASSERT(cp->ace == 0, ("detach but nonzero ace"));
552 KASSERT(cp->nstart == cp->nend,
553 ("detach with active requests"));
554 pp = cp->provider;
555 LIST_REMOVE(cp, consumers);

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

570
571int
572g_access(struct g_consumer *cp, int dcr, int dcw, int dce)
573{
574 struct g_provider *pp;
575 int pr,pw,pe;
576 int error;
577
578 g_topology_assert();
579 G_VALID_CONSUMER(cp);
576 pp = cp->provider;
580 pp = cp->provider;
581 G_VALID_PROVIDER(pp);
577
578 g_trace(G_T_ACCESS, "g_access(%p(%s), %d, %d, %d)",
579 cp, pp->name, dcr, dcw, dce);
580
582
583 g_trace(G_T_ACCESS, "g_access(%p(%s), %d, %d, %d)",
584 cp, pp->name, dcr, dcw, dce);
585
581 g_topology_assert();
582 KASSERT(cp->provider != NULL, ("access but not attached"));
583 KASSERT(cp->acr + dcr >= 0, ("access resulting in negative acr"));
584 KASSERT(cp->acw + dcw >= 0, ("access resulting in negative acw"));
585 KASSERT(cp->ace + dce >= 0, ("access resulting in negative ace"));
586 KASSERT(dcr != 0 || dcw != 0 || dce != 0, ("NOP access request"));
587 KASSERT(pp->geom->access != NULL, ("NULL geom->access"));
588
589 /*

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

683 bcopy(val, bp->bio_data, len);
684 bp->bio_completed = len;
685 }
686 g_io_deliver(bp, error);
687 return (1);
688}
689
690int
586 KASSERT(cp->provider != NULL, ("access but not attached"));
587 KASSERT(cp->acr + dcr >= 0, ("access resulting in negative acr"));
588 KASSERT(cp->acw + dcw >= 0, ("access resulting in negative acw"));
589 KASSERT(cp->ace + dce >= 0, ("access resulting in negative ace"));
590 KASSERT(dcr != 0 || dcw != 0 || dce != 0, ("NOP access request"));
591 KASSERT(pp->geom->access != NULL, ("NULL geom->access"));
592
593 /*

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

687 bcopy(val, bp->bio_data, len);
688 bp->bio_completed = len;
689 }
690 g_io_deliver(bp, error);
691 return (1);
692}
693
694int
691g_std_access(struct g_provider *pp __unused,
695g_std_access(struct g_provider *pp,
692 int dr __unused, int dw __unused, int de __unused)
693{
694
696 int dr __unused, int dw __unused, int de __unused)
697{
698
699 g_topology_assert();
700 G_VALID_PROVIDER(pp);
695 return (0);
696}
697
698void
699g_std_done(struct bio *bp)
700{
701 struct bio *bp2;
702

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

713/* XXX: maybe this is only g_slice_spoiled */
714
715void
716g_std_spoiled(struct g_consumer *cp)
717{
718 struct g_geom *gp;
719 struct g_provider *pp;
720
701 return (0);
702}
703
704void
705g_std_done(struct bio *bp)
706{
707 struct bio *bp2;
708

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

719/* XXX: maybe this is only g_slice_spoiled */
720
721void
722g_std_spoiled(struct g_consumer *cp)
723{
724 struct g_geom *gp;
725 struct g_provider *pp;
726
721 g_trace(G_T_TOPOLOGY, "g_std_spoiled(%p)", cp);
722 g_topology_assert();
727 g_topology_assert();
728 G_VALID_CONSUMER(cp);
729 g_trace(G_T_TOPOLOGY, "g_std_spoiled(%p)", cp);
723 g_detach(cp);
724 gp = cp->geom;
725 LIST_FOREACH(pp, &gp->provider, provider)
726 g_orphan_provider(pp, ENXIO);
727 g_destroy_consumer(cp);
728 if (LIST_EMPTY(&gp->provider) && LIST_EMPTY(&gp->consumer))
729 g_destroy_geom(gp);
730 else

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

747{
748 struct g_provider *pp;
749 struct g_consumer *cp, *cp2;
750
751 g_topology_assert();
752 if (flag == EV_CANCEL)
753 return;
754 pp = arg;
730 g_detach(cp);
731 gp = cp->geom;
732 LIST_FOREACH(pp, &gp->provider, provider)
733 g_orphan_provider(pp, ENXIO);
734 g_destroy_consumer(cp);
735 if (LIST_EMPTY(&gp->provider) && LIST_EMPTY(&gp->consumer))
736 g_destroy_geom(gp);
737 else

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

754{
755 struct g_provider *pp;
756 struct g_consumer *cp, *cp2;
757
758 g_topology_assert();
759 if (flag == EV_CANCEL)
760 return;
761 pp = arg;
762 G_VALID_PROVIDER(pp);
755 for (cp = LIST_FIRST(&pp->consumers); cp != NULL; cp = cp2) {
756 cp2 = LIST_NEXT(cp, consumers);
757 if (!cp->spoiled)
758 continue;
759 cp->spoiled = 0;
760 if (cp->geom->spoiled == NULL)
761 continue;
762 cp->geom->spoiled(cp);
763 g_topology_assert();
764 }
765}
766
767void
768g_spoil(struct g_provider *pp, struct g_consumer *cp)
769{
770 struct g_consumer *cp2;
771
772 g_topology_assert();
763 for (cp = LIST_FIRST(&pp->consumers); cp != NULL; cp = cp2) {
764 cp2 = LIST_NEXT(cp, consumers);
765 if (!cp->spoiled)
766 continue;
767 cp->spoiled = 0;
768 if (cp->geom->spoiled == NULL)
769 continue;
770 cp->geom->spoiled(cp);
771 g_topology_assert();
772 }
773}
774
775void
776g_spoil(struct g_provider *pp, struct g_consumer *cp)
777{
778 struct g_consumer *cp2;
779
780 g_topology_assert();
781 G_VALID_PROVIDER(pp);
782 G_VALID_CONSUMER(cp);
773
774 LIST_FOREACH(cp2, &pp->consumers, consumers) {
775 if (cp2 == cp)
776 continue;
777/*
778 KASSERT(cp2->acr == 0, ("spoiling cp->acr = %d", cp2->acr));
779 KASSERT(cp2->acw == 0, ("spoiling cp->acw = %d", cp2->acw));
780*/

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

793 error = g_io_getattr(attr, cp, &i, var);
794 if (error)
795 return (error);
796 if (i != len)
797 return (EINVAL);
798 return (0);
799}
800
783
784 LIST_FOREACH(cp2, &pp->consumers, consumers) {
785 if (cp2 == cp)
786 continue;
787/*
788 KASSERT(cp2->acr == 0, ("spoiling cp->acr = %d", cp2->acr));
789 KASSERT(cp2->acw == 0, ("spoiling cp->acw = %d", cp2->acw));
790*/

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

803 error = g_io_getattr(attr, cp, &i, var);
804 if (error)
805 return (error);
806 if (i != len)
807 return (EINVAL);
808 return (0);
809}
810
811#ifdef DIAGNOSTIC
801/*
812/*
802 * XXX: Bandaid for 5.2.
803 * XXX: DO NOT EVEN THINK ABOUT CALLING THIS FUNCTION!
813 * This function walks (topologically unsafely) the mesh and return a
814 * non-zero integer if it finds the argument pointer is an object.
815 * The return value indicates which type of object it is belived to be.
816 * If topology is not locked, this function is potentially dangerous,
817 * but since it is for debugging purposes and can be useful for instance
818 * from DDB, we do not assert topology lock is held.
804 */
819 */
805static int
820int
806g_valid_obj(void const *ptr)
807{
808 struct g_class *mp;
809 struct g_geom *gp;
810 struct g_consumer *cp;
811 struct g_provider *pp;
812
821g_valid_obj(void const *ptr)
822{
823 struct g_class *mp;
824 struct g_geom *gp;
825 struct g_consumer *cp;
826 struct g_provider *pp;
827
813 g_topology_assert();
814 LIST_FOREACH(mp, &g_classes, class) {
815 if (ptr == mp)
816 return (1);
817 LIST_FOREACH(gp, &mp->geom, geom) {
818 if (ptr == gp)
828 LIST_FOREACH(mp, &g_classes, class) {
829 if (ptr == mp)
830 return (1);
831 LIST_FOREACH(gp, &mp->geom, geom) {
832 if (ptr == gp)
819 return (1);
833 return (2);
820 LIST_FOREACH(cp, &gp->consumer, consumer)
821 if (ptr == cp)
834 LIST_FOREACH(cp, &gp->consumer, consumer)
835 if (ptr == cp)
822 return (1);
836 return (3);
823 LIST_FOREACH(pp, &gp->provider, provider)
824 if (ptr == pp)
837 LIST_FOREACH(pp, &gp->provider, provider)
838 if (ptr == pp)
825 return (1);
839 return (4);
826 }
827 }
828 return(0);
829}
840 }
841 }
842 return(0);
843}
830
831/*
832 * Check if the given pointer is a live object
833 */
834
835void
836g_sanity(void const *ptr)
837{
838 struct g_class *mp;
839 struct g_geom *gp;
840 struct g_consumer *cp;
841 struct g_provider *pp;
842
843 if (!(g_debugflags & 0x8))
844 return;
845 LIST_FOREACH(mp, &g_classes, class) {
846 KASSERT(mp != ptr, ("Ptr is live class"));
847 LIST_FOREACH(gp, &mp->geom, geom) {
848 KASSERT(gp != ptr, ("Ptr is live geom"));
849 KASSERT(gp->name != ptr, ("Ptr is live geom's name"));
850 LIST_FOREACH(cp, &gp->consumer, consumer) {
851 KASSERT(cp != ptr, ("Ptr is live consumer"));
852 }
853 LIST_FOREACH(pp, &gp->provider, provider) {
854 KASSERT(pp != ptr, ("Ptr is live provider"));
855 }
856 }
857 }
858}
859
844#endif