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 ---
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 ---