diff --git a/sys/geom/vinum/geom_vinum.c b/sys/geom/vinum/geom_vinum.c index f756132e9856..f33280a0c865 100644 --- a/sys/geom/vinum/geom_vinum.c +++ b/sys/geom/vinum/geom_vinum.c @@ -540,6 +540,7 @@ static int gv_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp) { struct g_geom *gp2; + struct g_consumer *cp; struct gv_softc *sc; struct gv_drive *d, *d2; struct gv_plex *p, *p2; @@ -560,6 +561,9 @@ gv_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp) */ LIST_FOREACH(d, &sc->drives, drive) { gp2 = d->geom; + cp = LIST_FIRST(&gp2->consumer); + if (cp != NULL) + g_access(cp, -1, -1, -1); if (gv_is_open(gp2)) return (EBUSY); } diff --git a/sys/geom/vinum/geom_vinum_drive.c b/sys/geom/vinum/geom_vinum_drive.c index 7a83c7783a2c..86eec15ff815 100644 --- a/sys/geom/vinum/geom_vinum_drive.c +++ b/sys/geom/vinum/geom_vinum_drive.c @@ -181,12 +181,14 @@ gv_drive_access(struct g_provider *pp, int dr, int dw, int de) } } +#if 0 /* On first open, grab an extra "exclusive" bit */ if (cp->acr == 0 && cp->acw == 0 && cp->ace == 0) de++; /* ... and let go of it on last close */ if ((cp->acr + dr) == 0 && (cp->acw + dw) == 0 && (cp->ace + de) == 1) de--; +#endif error = g_access(cp, dr, dw, de); if (error) { printf("FOOO: g_access failed: %d\n", error); @@ -294,6 +296,12 @@ gv_drive_orphan(struct g_consumer *cp) g_wither_geom(gp, error); } +static void +gv_drive_taste_orphan(struct g_consumer *cp) +{ + KASSERT(1 == 0, ("gv_drive_taste_orphan called: %s", cp->geom->name)); +} + static struct g_geom * gv_drive_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) { @@ -323,11 +331,7 @@ gv_drive_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) sc = gp2->softc; gp = g_new_geomf(mp, "%s.vinumdrive", pp->name); - gp->start = gv_drive_start; - gp->spoiled = gv_drive_orphan; - gp->orphan = gv_drive_orphan; - gp->access = gv_drive_access; - gp->start = gv_drive_start; + gp->orphan = gv_drive_taste_orphan; cp = g_new_consumer(gp); g_attach(cp, pp); @@ -357,6 +361,9 @@ gv_drive_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) */ g_topology_lock(); g_access(cp, -1, 0, 0); + g_detach(cp); + g_wither_geom(gp, ENXIO); + gp = NULL; d = gv_find_drive(sc, vhdr->label.name); @@ -387,6 +394,23 @@ gv_drive_taste(struct g_class *mp, struct g_provider *pp, int flags __unused) LIST_INSERT_HEAD(&sc->drives, d, drive); } + gp = g_new_geomf(mp, "%s.vinumdrive", pp->name); + gp->start = gv_drive_start; + gp->orphan = gv_drive_orphan; + gp->access = gv_drive_access; + gp->start = gv_drive_start; + + cp = g_new_consumer(gp); + g_attach(cp, pp); + error = g_access(cp, 1, 1, 1); + if (error) { + g_free(vhdr); + g_detach(cp); + g_destroy_consumer(cp); + g_destroy_geom(gp); + return (NULL); + } + gp->softc = d; d->geom = gp; strncpy(d->device, pp->name, GV_MAXDRIVENAME);