diff options
Diffstat (limited to 'sys/geom/vinum/geom_vinum_events.c')
-rw-r--r-- | sys/geom/vinum/geom_vinum_events.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/sys/geom/vinum/geom_vinum_events.c b/sys/geom/vinum/geom_vinum_events.c index b31611092576..78aa0adab8cf 100644 --- a/sys/geom/vinum/geom_vinum_events.c +++ b/sys/geom/vinum/geom_vinum_events.c @@ -195,6 +195,20 @@ failed: } /* + * Count completed BIOs and handle orphanization when all are done. + */ +void +gv_drive_done(struct gv_drive *d) +{ + + KASSERT(d->active >= 0, ("Negative number of BIOs (%d)", d->active)); + if (--d->active == 0 && (d->flags & GV_DRIVE_ORPHANED)) { + d->flags &= ~GV_DRIVE_ORPHANED; + gv_post_event(d->vinumconf, GV_EVENT_DRIVE_LOST, d, NULL, 0, 0); + } +} + +/* * When losing a drive (e.g. hardware failure), we cut down the consumer * attached to the underlying device and bring the drive itself to a * "referenced" state so that normal tasting could bring it up cleanly if it @@ -214,10 +228,10 @@ gv_drive_lost(struct gv_softc *sc, struct gv_drive *d) cp = d->consumer; if (cp != NULL) { - if (cp->nstart != cp->nend) { - G_VINUM_DEBUG(0, "dead drive '%s' has still active " + if (d->active > 0) { + G_VINUM_DEBUG(2, "dead drive '%s' has still active " "requests, unable to detach consumer", d->name); - gv_post_event(sc, GV_EVENT_DRIVE_LOST, d, NULL, 0, 0); + d->flags |= GV_DRIVE_ORPHANED; return; } g_topology_lock(); |