diff options
author | markj <markj@FreeBSD.org> | 2016-07-20 00:52:11 +0000 |
---|---|---|
committer | markj <markj@FreeBSD.org> | 2016-07-20 00:52:11 +0000 |
commit | 8ce51e3bdd922bd3660b1fd58646e79b413fb835 (patch) | |
tree | c403f03fbdbfb7bb12640e50a9a6d067a65f340d | |
parent | 68866de9f5dae35d9a9c8a54ce150925848f3c82 (diff) | |
download | FreeBSD-src-8ce51e3bdd922bd3660b1fd58646e79b413fb835.zip FreeBSD-src-8ce51e3bdd922bd3660b1fd58646e79b413fb835.tar.gz |
MFC r302091:
Do not complete pending gmirror BIOs when tearing down the provider.
-rw-r--r-- | sys/geom/mirror/g_mirror.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c index 13b0842..747d1f5 100644 --- a/sys/geom/mirror/g_mirror.c +++ b/sys/geom/mirror/g_mirror.c @@ -2127,8 +2127,21 @@ g_mirror_destroy_provider(struct g_mirror_softc *sc) g_topology_lock(); g_error_provider(sc->sc_provider, ENXIO); mtx_lock(&sc->sc_queue_mtx); - while ((bp = bioq_takefirst(&sc->sc_queue)) != NULL) - g_io_deliver(bp, ENXIO); + while ((bp = bioq_takefirst(&sc->sc_queue)) != NULL) { + /* + * Abort any pending I/O that wasn't generated by us. + * Synchronization requests and requests destined for individual + * mirror components can be destroyed immediately. + */ + if (bp->bio_to == sc->sc_provider && + bp->bio_from->geom != sc->sc_sync.ds_geom) { + g_io_deliver(bp, ENXIO); + } else { + if ((bp->bio_cflags & G_MIRROR_BIO_FLAG_SYNC) != 0) + free(bp->bio_data, M_MIRROR); + g_destroy_bio(bp); + } + } mtx_unlock(&sc->sc_queue_mtx); G_MIRROR_DEBUG(0, "Device %s: provider %s destroyed.", sc->sc_name, sc->sc_provider->name); |