svn commit: r356576 - stable/12/sys/geom/vinum
Alexander Motin
mav at FreeBSD.org
Fri Jan 10 00:41:17 UTC 2020
Author: mav
Date: Fri Jan 10 00:41:15 2020
New Revision: 356576
URL: https://svnweb.freebsd.org/changeset/base/356576
Log:
MFC r356108:
Modified:
stable/12/sys/geom/vinum/geom_vinum.h
stable/12/sys/geom/vinum/geom_vinum_events.c
stable/12/sys/geom/vinum/geom_vinum_plex.c
stable/12/sys/geom/vinum/geom_vinum_raid5.c
stable/12/sys/geom/vinum/geom_vinum_var.h
stable/12/sys/geom/vinum/geom_vinum_volume.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/sys/geom/vinum/geom_vinum.h
==============================================================================
--- stable/12/sys/geom/vinum/geom_vinum.h Fri Jan 10 00:39:44 2020 (r356575)
+++ stable/12/sys/geom/vinum/geom_vinum.h Fri Jan 10 00:41:15 2020 (r356576)
@@ -127,6 +127,7 @@ void gv_post_event(struct gv_softc *, int, void *, voi
void gv_worker_exit(struct gv_softc *);
struct gv_event *gv_get_event(struct gv_softc *);
void gv_remove_event(struct gv_softc *, struct gv_event *);
+void gv_drive_done(struct gv_drive *);
void gv_drive_tasted(struct gv_softc *, struct g_provider *);
void gv_drive_lost(struct gv_softc *, struct gv_drive *);
void gv_setup_objects(struct gv_softc *);
Modified: stable/12/sys/geom/vinum/geom_vinum_events.c
==============================================================================
--- stable/12/sys/geom/vinum/geom_vinum_events.c Fri Jan 10 00:39:44 2020 (r356575)
+++ stable/12/sys/geom/vinum/geom_vinum_events.c Fri Jan 10 00:41:15 2020 (r356576)
@@ -194,6 +194,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
@@ -213,10 +227,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();
Modified: stable/12/sys/geom/vinum/geom_vinum_plex.c
==============================================================================
--- stable/12/sys/geom/vinum/geom_vinum_plex.c Fri Jan 10 00:39:44 2020 (r356575)
+++ stable/12/sys/geom/vinum/geom_vinum_plex.c Fri Jan 10 00:41:15 2020 (r356576)
@@ -277,6 +277,7 @@ gv_plex_normal_request(struct gv_plex *p, struct bio *
cbp->bio_data = addr;
cbp->bio_done = gv_done;
cbp->bio_caller1 = s;
+ s->drive_sc->active++;
/* Store the sub-requests now and let others issue them. */
bioq_insert_tail(p->bqueue, cbp);
@@ -579,10 +580,10 @@ gv_sync_request(struct gv_plex *from, struct gv_plex *
return (ENOMEM);
}
bp->bio_length = length;
- bp->bio_done = gv_done;
+ bp->bio_done = NULL;
bp->bio_pflags |= GV_BIO_SYNCREQ;
bp->bio_offset = offset;
- bp->bio_caller1 = from;
+ bp->bio_caller1 = from;
bp->bio_caller2 = to;
bp->bio_cmd = type;
if (data == NULL)
@@ -693,7 +694,7 @@ gv_grow_request(struct gv_plex *p, off_t offset, off_t
}
bp->bio_cmd = type;
- bp->bio_done = gv_done;
+ bp->bio_done = NULL;
bp->bio_error = 0;
bp->bio_caller1 = p;
bp->bio_offset = offset;
@@ -801,7 +802,7 @@ gv_init_request(struct gv_sd *s, off_t start, caddr_t
}
bp->bio_cmd = BIO_WRITE;
bp->bio_data = data;
- bp->bio_done = gv_done;
+ bp->bio_done = NULL;
bp->bio_error = 0;
bp->bio_length = length;
bp->bio_pflags |= GV_BIO_INIT;
@@ -818,6 +819,7 @@ gv_init_request(struct gv_sd *s, off_t start, caddr_t
}
cbp->bio_done = gv_done;
cbp->bio_caller1 = s;
+ d->active++;
/* Send it off to the consumer. */
g_io_request(cbp, cp);
}
@@ -904,7 +906,7 @@ gv_parity_request(struct gv_plex *p, int flags, off_t
}
bp->bio_cmd = BIO_WRITE;
- bp->bio_done = gv_done;
+ bp->bio_done = NULL;
bp->bio_error = 0;
bp->bio_length = p->stripesize;
bp->bio_caller1 = p;
Modified: stable/12/sys/geom/vinum/geom_vinum_raid5.c
==============================================================================
--- stable/12/sys/geom/vinum/geom_vinum_raid5.c Fri Jan 10 00:39:44 2020 (r356575)
+++ stable/12/sys/geom/vinum/geom_vinum_raid5.c Fri Jan 10 00:41:15 2020 (r356576)
@@ -92,11 +92,13 @@ gv_raid5_start(struct gv_plex *p, struct bio *bp, cadd
if (wp->waiting != NULL) {
if (wp->waiting->bio_cflags & GV_BIO_MALLOC)
g_free(wp->waiting->bio_data);
+ gv_drive_done(wp->waiting->bio_caller1);
g_destroy_bio(wp->waiting);
}
if (wp->parity != NULL) {
if (wp->parity->bio_cflags & GV_BIO_MALLOC)
g_free(wp->parity->bio_data);
+ gv_drive_done(wp->parity->bio_caller1);
g_destroy_bio(wp->parity);
}
g_free(wp);
@@ -117,6 +119,7 @@ gv_raid5_start(struct gv_plex *p, struct bio *bp, cadd
while (cbp != NULL) {
if (cbp->bio_cflags & GV_BIO_MALLOC)
g_free(cbp->bio_data);
+ gv_drive_done(cbp->bio_caller1);
g_destroy_bio(cbp);
cbp = bioq_takefirst(p->bqueue);
}
@@ -656,6 +659,7 @@ gv_raid5_clone_bio(struct bio *bp, struct gv_sd *s, st
cbp->bio_length = wp->length;
cbp->bio_done = gv_done;
cbp->bio_caller1 = s;
+ s->drive_sc->active++;
if (use_wp)
cbp->bio_caller2 = wp;
Modified: stable/12/sys/geom/vinum/geom_vinum_var.h
==============================================================================
--- stable/12/sys/geom/vinum/geom_vinum_var.h Fri Jan 10 00:39:44 2020 (r356575)
+++ stable/12/sys/geom/vinum/geom_vinum_var.h Fri Jan 10 00:41:15 2020 (r356576)
@@ -260,10 +260,12 @@ struct gv_drive {
#define GV_DRIVE_REFERENCED 0x01 /* The drive isn't really existing,
but was referenced by a subdisk
during taste. */
+#define GV_DRIVE_ORPHANED 0x02 /* The drive was orphaned. */
struct gv_hdr *hdr; /* The drive header. */
struct g_consumer *consumer; /* Consumer attached to this drive. */
+ int active; /* Number of active requests. */
int freelist_entries; /* Count of freelist entries. */
LIST_HEAD(,gv_freelist) freelist; /* List of freelist entries. */
Modified: stable/12/sys/geom/vinum/geom_vinum_volume.c
==============================================================================
--- stable/12/sys/geom/vinum/geom_vinum_volume.c Fri Jan 10 00:39:44 2020 (r356575)
+++ stable/12/sys/geom/vinum/geom_vinum_volume.c Fri Jan 10 00:41:15 2020 (r356576)
@@ -163,4 +163,6 @@ gv_bio_done(struct gv_softc *sc, struct bio *bp)
gv_plex_raid5_done(p, bp);
break;
}
+
+ gv_drive_done(s->drive_sc);
}
More information about the svn-src-stable
mailing list