aboutsummaryrefslogtreecommitdiff
path: root/sys/geom
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2017-04-14 16:54:50 +0000
committerMark Johnston <markj@FreeBSD.org>2017-04-14 16:54:50 +0000
commita65d524afc882d2d5a494a95c5184f76e2d3c7d4 (patch)
tree60b6cac68a9560b37751f583207600f37c2bdd48 /sys/geom
parent07bb15b4400bd1799ee2c1bebd211df6140048f0 (diff)
downloadsrc-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.c9
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