aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Libby <rlibby@FreeBSD.org>2019-07-01 22:06:36 +0000
committerRyan Libby <rlibby@FreeBSD.org>2019-07-01 22:06:36 +0000
commit9167705c8ce7d27a02cbb3e758cba3635910a430 (patch)
treee7d68bf225a19c5e36fb7b044b702757c242e98a
parent3bb6e0f0c7f6012dc91c23520be4660a3fc96e8e (diff)
downloadsrc-9167705c8ce7d27a02cbb3e758cba3635910a430.tar.gz
src-9167705c8ce7d27a02cbb3e758cba3635910a430.zip
g_mirror_taste: avoid deadlock, always clear tasting flag
If g_mirror_taste encountered an error at g_mirror_add_disk, it might try to g_mirror_destroy the device with the G_MIRROR_DEVICE_FLAG_TASTING flag still set. This would wait on a worker to complete the destruction with g_mirror_try_destroy, but that function bails out if the tasting flag is set, resulting in a deadlock. Clear the tasting flag before trying to destroy the device. Test Plan: sysctl debug.fail_point.mnowait="1%return" kyua test -k /usr/tests/sys/geom/class/mirror/Kyuafile Reviewed by: markj Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D20744
Notes
Notes: svn path=/head/; revision=349587
-rw-r--r--sys/geom/mirror/g_mirror.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c
index 5cc1b4a0c365..0fd9fe33ba78 100644
--- a/sys/geom/mirror/g_mirror.c
+++ b/sys/geom/mirror/g_mirror.c
@@ -3291,6 +3291,7 @@ g_mirror_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
sx_xlock(&sc->sc_lock);
sc->sc_flags |= G_MIRROR_DEVICE_FLAG_TASTING;
error = g_mirror_add_disk(sc, pp, &md);
+ sc->sc_flags &= ~G_MIRROR_DEVICE_FLAG_TASTING;
if (error != 0) {
G_MIRROR_DEBUG(0, "Cannot add disk %s to %s (error=%d).",
pp->name, gp->name, error);
@@ -3302,7 +3303,6 @@ g_mirror_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
}
gp = NULL;
}
- sc->sc_flags &= ~G_MIRROR_DEVICE_FLAG_TASTING;
if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) != 0) {
g_mirror_destroy(sc, G_MIRROR_DESTROY_HARD);
g_topology_lock();