Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Jan 2020 00:41:15 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r356576 - stable/12/sys/geom/vinum
Message-ID:  <202001100041.00A0fFF0015622@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202001100041.00A0fFF0015622>