diff options
author | Mark Johnston <markj@FreeBSD.org> | 2017-04-14 16:54:50 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2017-04-14 16:54:50 +0000 |
commit | a65d524afc882d2d5a494a95c5184f76e2d3c7d4 (patch) | |
tree | 60b6cac68a9560b37751f583207600f37c2bdd48 /sys/geom | |
parent | 07bb15b4400bd1799ee2c1bebd211df6140048f0 (diff) | |
download | src-a65d524afc882d2d5a494a95c5184f76e2d3c7d4.tar.gz src-a65d524afc882d2d5a494a95c5184f76e2d3c7d4.zip |
Stop mirror synchronization before draining the I/O queue.
Regular I/O requests may be blocked by concurrent synchronization requests
targeted to the same LBAs, in which case they are moved to a holding queue
until the conflicting I/O completes. We therefore want to stop
synchronization before completing pending I/O in g_mirror_destroy_provider()
since this ensures that blocked I/O requests are completed as well.
Tested by: pho
MFC after: 2 weeks
Sponsored by: Dell EMC Isilon
Notes
Notes:
svn path=/head/; revision=316859
Diffstat (limited to 'sys/geom')
-rw-r--r-- | sys/geom/mirror/g_mirror.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c index 7e5664e681dd..22ce67104281 100644 --- a/sys/geom/mirror/g_mirror.c +++ b/sys/geom/mirror/g_mirror.c @@ -2170,6 +2170,11 @@ g_mirror_destroy_provider(struct g_mirror_softc *sc) KASSERT(sc->sc_provider != NULL, ("NULL provider (device=%s).", sc->sc_name)); + LIST_FOREACH(disk, &sc->sc_disks, d_next) { + if (disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING) + g_mirror_sync_stop(disk, 1); + } + g_topology_lock(); g_error_provider(sc->sc_provider, ENXIO); mtx_lock(&sc->sc_queue_mtx); @@ -2193,10 +2198,6 @@ g_mirror_destroy_provider(struct g_mirror_softc *sc) sc->sc_provider = NULL; G_MIRROR_DEBUG(0, "Device %s: provider destroyed.", sc->sc_name); g_topology_unlock(); - LIST_FOREACH(disk, &sc->sc_disks, d_next) { - if (disk->d_state == G_MIRROR_DISK_STATE_SYNCHRONIZING) - g_mirror_sync_stop(disk, 1); - } } static void |