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);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to