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 --- 18 unchanged lines hidden (view full) --- 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * |
35 * $FreeBSD: head/sys/geom/geom_subr.c 93248 2002-03-26 21:40:06Z phk $ |
36 */ 37 38 39#include <sys/param.h> 40#ifndef _KERNEL 41#include <stdio.h> 42#include <unistd.h> 43#include <stdlib.h> --- 11 unchanged lines hidden (view full) --- 55#include <sys/lock.h> 56#include <sys/mutex.h> 57#endif 58#include <sys/errno.h> 59#include <sys/sbuf.h> 60#include <geom/geom.h> 61#include <machine/stdarg.h> 62 |
63struct class_list_head g_classs = LIST_HEAD_INITIALIZER(g_classs); |
64static struct g_tailq_head geoms = TAILQ_HEAD_INITIALIZER(geoms); 65static int g_nproviders; 66char *g_wait_event, *g_wait_up, *g_wait_down, *g_wait_sim; 67 68static int g_ignition; 69 70void |
71g_add_class(struct g_class *mp) |
72{ 73 74 if (!g_ignition) { 75 g_ignition++; 76 g_init(); 77 } 78 g_topology_lock(); |
79 g_trace(G_T_TOPOLOGY, "g_add_class(%s)", mp->name); |
80 LIST_INIT(&mp->geom); |
81 LIST_INSERT_HEAD(&g_classs, mp, class); |
82 if (g_nproviders > 0) |
83 g_post_event(EV_NEW_CLASS, mp, NULL, NULL, NULL); |
84 g_topology_unlock(); 85} 86 87struct g_geom * |
88g_new_geomf(struct g_class *mp, char *fmt, ...) |
89{ 90 struct g_geom *gp; 91 va_list ap; 92 struct sbuf *sb; 93 94 g_topology_assert(); 95 va_start(ap, fmt); 96 mtx_lock(&Giant); 97 sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 98 sbuf_vprintf(sb, fmt, ap); 99 sbuf_finish(sb); 100 mtx_unlock(&Giant); 101 gp = g_malloc(sizeof *gp + sbuf_len(sb) + 1, M_WAITOK | M_ZERO); 102 gp->name = (char *)(gp + 1); |
103 gp->class = mp; |
104 gp->rank = 1; 105 LIST_INIT(&gp->consumer); 106 LIST_INIT(&gp->provider); 107 LIST_INSERT_HEAD(&mp->geom, gp, geom); 108 TAILQ_INSERT_HEAD(&geoms, gp, geoms); 109 strcpy(gp->name, sbuf_data(sb)); 110 sbuf_delete(sb); 111 return (gp); --- 18 unchanged lines hidden (view full) --- 130} 131 132struct g_consumer * 133g_new_consumer(struct g_geom *gp) 134{ 135 struct g_consumer *cp; 136 137 g_topology_assert(); |
138 KASSERT(gp->class->orphan != NULL, 139 ("g_new_consumer on class(%s) without orphan", gp->class->name)); |
140 141 cp = g_malloc(sizeof *cp, M_WAITOK | M_ZERO); 142 cp->geom = gp; 143 LIST_INSERT_HEAD(&gp->consumer, cp, consumer); 144 return(cp); 145} 146 147void --- 224 unchanged lines hidden (view full) --- 372 g_trace(G_T_ACCESS, "g_access_rel(%p(%s), %d, %d, %d)", 373 cp, pp->name, dcr, dcw, dce); 374 375 g_topology_assert(); 376 KASSERT(cp->provider != NULL, ("access but not attached")); 377 KASSERT(cp->acr + dcr >= 0, ("access resulting in negative acr")); 378 KASSERT(cp->acw + dcw >= 0, ("access resulting in negative acw")); 379 KASSERT(cp->ace + dce >= 0, ("access resulting in negative ace")); |
380 KASSERT(pp->geom->class->access != NULL, ("NULL class->access")); |
381 382 /* |
383 * If our class cares about being spoiled, and we have been, we |
384 * are probably just ahead of the event telling us that. Fail 385 * now rather than having to unravel this later. 386 */ 387 if (cp->geom->spoiled != NULL && cp->spoiled) { 388 KASSERT(dcr >= 0, ("spoiled but dcr = %d", dcr)); 389 KASSERT(dcw >= 0, ("spoiled but dce = %d", dcw)); 390 KASSERT(dce >= 0, ("spoiled but dcw = %d", dce)); 391 KASSERT(cp->acr == 0, ("spoiled but cp->acr = %d", cp->acr)); --- 33 unchanged lines hidden (view full) --- 425 * If we open first write, spoil any partner consumers. 426 * If we close last write, trigger re-taste. 427 */ 428 if (pp->acw == 0 && dcw != 0) 429 g_spoil(pp, cp); 430 else if (pp->acw != 0 && pp->acw == -dcw && !(pp->geom->flags & G_GEOM_WITHER)) 431 g_post_event(EV_NEW_PROVIDER, NULL, NULL, pp, NULL); 432 |
433 error = pp->geom->class->access(pp, dcr, dcw, dce); |
434 if (!error) { 435 pp->acr += dcr; 436 pp->acw += dcw; 437 pp->ace += dce; 438 cp->acr += dcr; 439 cp->acw += dcw; 440 cp->ace += dce; 441 } --- 102 unchanged lines hidden (view full) --- 544 KASSERT(cp2->acw == 0, ("spoiling cp->acw = %d", cp2->acw)); 545*/ 546 KASSERT(cp2->ace == 0, ("spoiling cp->ace = %d", cp2->ace)); 547 cp2->spoiled++; 548 } 549 g_post_event(EV_SPOILED, NULL, NULL, pp, cp); 550} 551 |
552static struct g_class * 553g_class_by_name(char *name) |
554{ |
555 struct g_class *mp; |
556 |
557 g_trace(G_T_TOPOLOGY, "g_class_by_name(%s)", name); |
558 g_topology_assert(); |
559 LIST_FOREACH(mp, &g_classs, class) |
560 if (!strcmp(mp->name, name)) 561 return (mp); 562 return (NULL); 563} 564 565struct g_geom * |
566g_create_geomf(char *class, struct g_provider *pp, char *fmt, ...) |
567{ 568 va_list ap; 569 struct sbuf *sb; 570 char *s; |
571 struct g_class *mp; |
572 struct g_geom *gp; 573 |
574 g_trace(G_T_TOPOLOGY, "g_create_geom(%s, %p(%s))", class, |
575 pp, pp == NULL ? "" : pp->name); 576 g_topology_assert(); 577 gp = NULL; |
578 mp = g_class_by_name(class); |
579 if (mp == NULL) 580 return (NULL); 581 if (fmt != NULL) { 582 va_start(ap, fmt); 583 mtx_lock(&Giant); 584 sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); 585 sbuf_vprintf(sb, fmt, ap); 586 sbuf_finish(sb); --- 8 unchanged lines hidden (view full) --- 595 return (NULL); 596 if (gp == NULL) 597 gp = mp->create_geom(mp, pp, s); 598 /* XXX: delete sbuf */ 599 return (gp); 600} 601 602struct g_geom * |
603g_insert_geom(char *class, struct g_consumer *cp) |
604{ |
605 struct g_class *mp; |
606 struct g_geom *gp; 607 struct g_provider *pp, *pp2; 608 struct g_consumer *cp2; 609 int error; 610 |
611 g_trace(G_T_TOPOLOGY, "g_insert_geomf(%s, %p)", class, cp); |
612 g_topology_assert(); 613 KASSERT(cp->provider != NULL, ("g_insert_geomf but not attached")); 614 /* XXX: check for events ?? */ |
615 mp = g_class_by_name(class); |
616 if (mp == NULL) 617 return (NULL); 618 if (mp->create_geom == NULL) 619 return (NULL); 620 pp = cp->provider; 621 gp = mp->taste(mp, pp, NULL, G_TF_TRANSPARENT); 622 if (gp == NULL) 623 return (NULL); --- 16 unchanged lines hidden --- |