Index: geom.h =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom.h,v retrieving revision 1.80 diff -u -p -r1.80 geom.h --- geom.h 12 Feb 2004 22:42:11 -0000 1.80 +++ geom.h 21 Feb 2004 16:37:18 -0000 @@ -64,7 +64,7 @@ typedef int g_ctl_destroy_geom_t (struct typedef int g_ctl_config_geom_t (struct gctl_req *, struct g_geom *gp, const char *verb); typedef void g_init_t (struct g_class *mp); typedef void g_fini_t (struct g_class *mp); -typedef struct g_geom * g_taste_t (struct g_class *, struct g_provider *, int flags); +typedef struct g_geom * g_taste_t (struct g_class *, struct g_provider *, struct g_consumer *cp, int flags); typedef int g_ioctl_t(struct g_provider *pp, u_long cmd, void *data, struct thread *td); #define G_TF_NORMAL 0 #define G_TF_INSIST 1 Index: geom_aes.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom_aes.c,v retrieving revision 1.24 diff -u -p -r1.24 geom_aes.c --- geom_aes.c 12 Feb 2004 22:42:11 -0000 1.24 +++ geom_aes.c 21 Feb 2004 16:42:23 -0000 @@ -270,7 +270,8 @@ g_aes_access(struct g_provider *pp, int } static struct g_geom * -g_aes_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) +g_aes_taste(struct g_class *mp, struct g_provider *pp, struct g_consumer *_cp, + int flags __unused) { struct g_geom *gp; struct g_consumer *cp; Index: geom_apple.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom_apple.c,v retrieving revision 1.13 diff -u -p -r1.13 geom_apple.c --- geom_apple.c 12 Feb 2004 22:42:11 -0000 1.13 +++ geom_apple.c 21 Feb 2004 16:43:08 -0000 @@ -139,7 +139,8 @@ g_apple_print() #endif static struct g_geom * -g_apple_taste(struct g_class *mp, struct g_provider *pp, int insist) +g_apple_taste(struct g_class *mp, struct g_provider *pp, struct g_consumer *_cp, + int insist) { struct g_geom *gp; struct g_consumer *cp; Index: geom_bsd.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom_bsd.c,v retrieving revision 1.68 diff -u -p -r1.68 geom_bsd.c --- geom_bsd.c 14 Feb 2004 17:59:44 -0000 1.68 +++ geom_bsd.c 21 Feb 2004 18:29:52 -0000 @@ -458,7 +458,8 @@ g_bsd_dumpconf(struct sbuf *sb, const ch */ static struct g_geom * -g_bsd_taste(struct g_class *mp, struct g_provider *pp, int flags) +g_bsd_taste(struct g_class *mp, struct g_provider *pp, struct g_consumer *_cp, + int flags) { struct g_geom *gp; struct g_consumer *cp; Index: geom_dev.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom_dev.c,v retrieving revision 1.72 diff -u -p -r1.72 geom_dev.c --- geom_dev.c 12 Feb 2004 22:42:11 -0000 1.72 +++ geom_dev.c 21 Feb 2004 18:30:21 -0000 @@ -148,7 +148,8 @@ g_dev_getprovider(dev_t dev) static struct g_geom * -g_dev_taste(struct g_class *mp, struct g_provider *pp, int insist __unused) +g_dev_taste(struct g_class *mp, struct g_provider *pp, struct g_consumer *_cp, + int insist __unused) { struct g_geom *gp; struct g_consumer *cp; Index: geom_fox.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom_fox.c,v retrieving revision 1.6 diff -u -p -r1.6 geom_fox.c --- geom_fox.c 14 Feb 2004 17:59:44 -0000 1.6 +++ geom_fox.c 21 Feb 2004 18:30:48 -0000 @@ -339,7 +339,8 @@ g_fox_access(struct g_provider *pp, int } static struct g_geom * -g_fox_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) +g_fox_taste(struct g_class *mp, struct g_provider *pp, struct g_consumer *_cp, + int flags __unused) { struct g_geom *gp, *gp2; struct g_provider *pp2; Index: geom_gpt.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom_gpt.c,v retrieving revision 1.27 diff -u -p -r1.27 geom_gpt.c --- geom_gpt.c 12 Feb 2004 22:42:11 -0000 1.27 +++ geom_gpt.c 21 Feb 2004 18:31:19 -0000 @@ -107,7 +107,8 @@ g_gpt_dumpconf(struct sbuf *sb, const ch } static struct g_geom * -g_gpt_taste(struct g_class *mp, struct g_provider *pp, int insist) +g_gpt_taste(struct g_class *mp, struct g_provider *pp, struct g_consumer *_cp, + int insist) { struct g_consumer *cp; struct g_geom *gp; Index: geom_mbr.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom_mbr.c,v retrieving revision 1.56 diff -u -p -r1.56 geom_mbr.c --- geom_mbr.c 12 Feb 2004 22:42:11 -0000 1.56 +++ geom_mbr.c 21 Feb 2004 18:32:26 -0000 @@ -226,7 +226,8 @@ g_mbr_dumpconf(struct sbuf *sb, const ch } static struct g_geom * -g_mbr_taste(struct g_class *mp, struct g_provider *pp, int insist) +g_mbr_taste(struct g_class *mp, struct g_provider *pp, struct g_consumer *_cp, + int insist) { struct g_geom *gp; struct g_consumer *cp; @@ -323,7 +324,8 @@ g_mbrext_dumpconf(struct sbuf *sb, const } static struct g_geom * -g_mbrext_taste(struct g_class *mp, struct g_provider *pp, int insist __unused) +g_mbrext_taste(struct g_class *mp, struct g_provider *pp, + struct g_consumer *_cp, int insist __unused) { struct g_geom *gp; struct g_consumer *cp; Index: geom_mirror.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom_mirror.c,v retrieving revision 1.11 diff -u -p -r1.11 geom_mirror.c --- geom_mirror.c 12 Feb 2004 22:42:11 -0000 1.11 +++ geom_mirror.c 21 Feb 2004 18:33:15 -0000 @@ -157,7 +157,8 @@ g_mirror_access(struct g_provider *pp, i } static struct g_geom * -g_mirror_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) +g_mirror_taste(struct g_class *mp, struct g_provider *pp, + struct g_consumer *_cp, int flags __unused) { struct g_geom *gp, *gp2; struct g_provider *pp2; Index: geom_pc98.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom_pc98.c,v retrieving revision 1.45 diff -u -p -r1.45 geom_pc98.c --- geom_pc98.c 12 Feb 2004 22:42:11 -0000 1.45 +++ geom_pc98.c 21 Feb 2004 18:33:41 -0000 @@ -220,7 +220,8 @@ g_pc98_dumpconf(struct sbuf *sb, const c } static struct g_geom * -g_pc98_taste(struct g_class *mp, struct g_provider *pp, int flags) +g_pc98_taste(struct g_class *mp, struct g_provider *pp, struct g_consumer *_cp, + int flags) { struct g_geom *gp; struct g_consumer *cp; Index: geom_subr.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom_subr.c,v retrieving revision 1.71 diff -u -p -r1.71 geom_subr.c --- geom_subr.c 14 Feb 2004 17:58:57 -0000 1.71 +++ geom_subr.c 21 Feb 2004 16:39:29 -0000 @@ -64,6 +64,13 @@ struct g_hh00 { int error; }; +static void +g_impossible_orphan(struct g_consumer *cp) +{ + + KASSERT(1 == 0, ("Orphan while tasting (%s).", cp->provider->name)); +} + /* * This event offers a new class a chance to taste all preexisting providers. */ @@ -72,8 +79,9 @@ g_load_class(void *arg, int flag) { struct g_hh00 *hh; struct g_class *mp2, *mp; - struct g_geom *gp; + struct g_geom *gp, *tgp; struct g_provider *pp; + struct g_consumer *tcp; g_topology_assert(); if (flag == EV_CANCEL) /* XXX: can't happen ? */ @@ -100,16 +108,35 @@ g_load_class(void *arg, int flag) mp->init(mp); if (mp->taste == NULL) return; + tgp = g_new_geomf(mp, "%s:taste", mp->name); + if (tgp == NULL) + return; + tgp->orphan = g_impossible_orphan; + tcp = g_new_consumer(tgp); + if (tcp == NULL) { + g_destroy_geom(tgp); + return; + } LIST_FOREACH(mp2, &g_classes, class) { if (mp == mp2) continue; LIST_FOREACH(gp, &mp2->geom, geom) { LIST_FOREACH(pp, &gp->provider, provider) { - mp->taste(mp, pp, 0); + if (g_attach(tcp, pp) != 0) + continue; + if (g_access(tcp, 1, 0, 0) != 0) { + g_detach(tcp); + continue; + } + mp->taste(mp, pp, tcp, 0); g_topology_assert(); + g_access(tcp, -1, 0, 0); + g_detach(tcp); } } } + g_destroy_consumer(tcp); + g_destroy_geom(tgp); } static void @@ -337,8 +364,9 @@ static void g_new_provider_event(void *arg, int flag) { struct g_class *mp; + struct g_geom *tgp; struct g_provider *pp; - struct g_consumer *cp; + struct g_consumer *cp, *tcp; int i; g_topology_assert(); @@ -347,6 +375,15 @@ g_new_provider_event(void *arg, int flag if (g_shutdown) return; pp = arg; + tgp = g_new_geomf(mp, "%s:taste", pp->geom->class->name); + if (tgp == NULL) + return; + tgp->orphan = g_impossible_orphan; + tcp = g_new_consumer(tgp); + if (tcp == NULL) { + g_destroy_geom(tgp); + return; + } LIST_FOREACH(mp, &g_classes, class) { if (mp->taste == NULL) continue; @@ -356,17 +393,27 @@ g_new_provider_event(void *arg, int flag i = 0; if (!i) continue; - mp->taste(mp, pp, 0); + if (g_attach(tcp, pp) != 0) + continue; + if (g_access(tcp, 1, 0, 0) != 0) { + g_detach(tcp); + continue; + } + mp->taste(mp, pp, tcp, 0); g_topology_assert(); + g_access(tcp, -1, 0, 0); + g_detach(tcp); /* * XXX: Bandaid for 5.2-RELEASE * XXX: DO NOT REPLICATE THIS CODE! */ if (!g_valid_obj(pp)) { printf("g_provider %p disappeared while tasting\n", pp); - return; + break; } } + g_destroy_consumer(tcp); + g_destroy_geom(tgp); } Index: geom_sunlabel.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom_sunlabel.c,v retrieving revision 1.41 diff -u -p -r1.41 geom_sunlabel.c --- geom_sunlabel.c 12 Feb 2004 22:42:11 -0000 1.41 +++ geom_sunlabel.c 21 Feb 2004 18:34:05 -0000 @@ -225,7 +225,8 @@ g_sunlabel_config(struct gctl_req *req, } static struct g_geom * -g_sunlabel_taste(struct g_class *mp, struct g_provider *pp, int flags) +g_sunlabel_taste(struct g_class *mp, struct g_provider *pp, + struct g_consumer *_cp, int flags) { struct g_geom *gp; struct g_consumer *cp; Index: geom_vol_ffs.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/geom_vol_ffs.c,v retrieving revision 1.11 diff -u -p -r1.11 geom_vol_ffs.c --- geom_vol_ffs.c 12 Feb 2004 22:42:11 -0000 1.11 +++ geom_vol_ffs.c 21 Feb 2004 18:34:29 -0000 @@ -57,7 +57,8 @@ g_vol_ffs_start(struct bio *bp __unused) } static struct g_geom * -g_vol_ffs_taste(struct g_class *mp, struct g_provider *pp, int flags) +g_vol_ffs_taste(struct g_class *mp, struct g_provider *pp, + struct g_consumer *_cp, int flags) { struct g_geom *gp; struct g_consumer *cp; Index: concat/g_concat.c =================================================================== RCS file: /private/FreeBSD/src/sys/geom/concat/g_concat.c,v retrieving revision 1.1 diff -u -p -r1.1 g_concat.c --- concat/g_concat.c 19 Feb 2004 15:19:49 -0000 1.1 +++ concat/g_concat.c 21 Feb 2004 18:29:18 -0000 @@ -522,7 +522,8 @@ g_concat_destroy_geom(struct gctl_req *r } static struct g_geom * -g_concat_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) +g_concat_taste(struct g_class *mp, struct g_provider *pp, + struct g_consumer *_cp, int flags __unused) { struct g_concat_metadata md; struct g_concat_softc *sc;