Index: sys/geom/vinum/geom_vinum.c =================================================================== --- sys/geom/vinum/geom_vinum.c (revision 189454) +++ sys/geom/vinum/geom_vinum.c (working copy) @@ -1009,6 +1009,10 @@ bp->bio_cflags &= ~GV_BIO_ONHOLD; g_io_request(bp, s->drive_sc->consumer); } + /* A special request requireing special handling. */ + } else if (bp->bio_cflags & GV_BIO_INTERNAL) { + p = bp->bio_caller1; + gv_plex_start(p, bp); /* A fresh bio, scheduled it down. */ } else { gv_volume_start(sc, bp); Index: sys/geom/vinum/geom_vinum_plex.c =================================================================== --- sys/geom/vinum/geom_vinum_plex.c (revision 189454) +++ sys/geom/vinum/geom_vinum_plex.c (working copy) @@ -566,10 +566,13 @@ gv_sync_request(struct gv_plex *from, struct gv_plex *to, off_t offset, off_t length, int type, caddr_t data) { + struct gv_softc *sc; struct bio *bp; KASSERT(from != NULL, ("NULL from")); KASSERT(to != NULL, ("NULL to")); + sc = from->vinumconf; + KASSERT(sc != NULL, ("NULL sc")); bp = g_new_bio(); if (bp == NULL) { @@ -581,6 +584,7 @@ bp->bio_done = gv_done; bp->bio_cflags |= GV_BIO_SYNCREQ; bp->bio_offset = offset; + bp->bio_caller1 = from; bp->bio_caller2 = to; bp->bio_cmd = type; if (data == NULL) @@ -589,7 +593,10 @@ bp->bio_data = data; /* Send down next. */ - gv_plex_start(from, bp); + mtx_lock(&sc->queue_mtx); + bioq_disksort(sc->bqueue, bp); + mtx_unlock(&sc->queue_mtx); + //gv_plex_start(from, bp); return (0); } @@ -681,9 +688,13 @@ gv_grow_request(struct gv_plex *p, off_t offset, off_t length, int type, caddr_t data) { + struct gv_softc *sc; struct bio *bp; KASSERT(p != NULL, ("gv_grow_request: NULL p")); + sc = p->vinumconf; + KASSERT(sc != NULL, ("gv_grow_request: NULL sc")); + bp = g_new_bio(); if (bp == NULL) { G_VINUM_DEBUG(0, "grow of %s failed creating bio: " @@ -694,6 +705,7 @@ bp->bio_cmd = type; bp->bio_done = gv_done; bp->bio_error = 0; + bp->bio_caller1 = p; bp->bio_offset = offset; bp->bio_length = length; bp->bio_pflags |= GV_BIO_SYNCREQ; /* XXX: misuse of pflags AND syncreq.*/ @@ -702,8 +714,10 @@ bp->bio_cflags |= GV_BIO_MALLOC; bp->bio_data = data; - /* Send down. */ - gv_plex_start(p, bp); + mtx_lock(&sc->queue_mtx); + bioq_disksort(sc->bqueue, bp); + mtx_unlock(&sc->queue_mtx); + //gv_plex_start(p, bp); return (0); } @@ -887,9 +901,12 @@ void gv_parity_request(struct gv_plex *p, int flags, off_t offset) { + struct gv_softc *sc; struct bio *bp; KASSERT(p != NULL, ("gv_parity_request: NULL p")); + sc = p->vinumconf; + KASSERT(sc != NULL, ("gv_parity_request: NULL sc")); bp = g_new_bio(); if (bp == NULL) { @@ -902,6 +919,7 @@ bp->bio_done = gv_done; bp->bio_error = 0; bp->bio_length = p->stripesize; + bp->bio_caller1 = p; /* * Check if it's a rebuild of a degraded plex or a user request of @@ -921,8 +939,10 @@ /* We still have more parity to build. */ bp->bio_offset = offset; - - gv_plex_start(p, bp); /* Send it down to the plex. */ + mtx_lock(&sc->queue_mtx); + bioq_disksort(sc->bqueue, bp); + mtx_unlock(&sc->queue_mtx); + //gv_plex_start(p, bp); /* Send it down to the plex. */ } /*