Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140257057
D24780.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D24780.id.diff
View Options
Index: head/sys/geom/mirror/g_mirror_ctl.c
===================================================================
--- head/sys/geom/mirror/g_mirror_ctl.c
+++ head/sys/geom/mirror/g_mirror_ctl.c
@@ -44,6 +44,10 @@
#include <geom/geom_int.h>
#include <geom/mirror/g_mirror.h>
+/*
+ * Configure, Rebuild, Remove, Deactivate, Forget, and Stop operations do not
+ * seem to depend on any particular g_mirror initialization state.
+ */
static struct g_mirror_softc *
g_mirror_find_device(struct g_class *mp, const char *name)
{
@@ -61,6 +65,10 @@
strcmp(sc->sc_name, name) == 0) {
g_topology_unlock();
sx_xlock(&sc->sc_lock);
+ if ((sc->sc_flags & G_MIRROR_DEVICE_FLAG_DESTROY) != 0) {
+ sx_xunlock(&sc->sc_lock);
+ return (NULL);
+ }
return (sc);
}
}
@@ -68,6 +76,55 @@
return (NULL);
}
+/* Insert and Resize operations depend on a launched GEOM (sc_provider). */
+#define GMFL_VALID_FLAGS (M_WAITOK | M_NOWAIT)
+static struct g_mirror_softc *
+g_mirror_find_launched_device(struct g_class *mp, const char *name, int flags)
+{
+ struct g_mirror_softc *sc;
+ int error;
+
+ KASSERT((flags & ~GMFL_VALID_FLAGS) == 0 &&
+ flags != GMFL_VALID_FLAGS && flags != 0,
+ ("%s: Invalid flags %x\n", __func__, (unsigned)flags));
+#undef GMFL_VALID_FLAGS
+
+ while (true) {
+ sc = g_mirror_find_device(mp, name);
+ if (sc == NULL)
+ return (NULL);
+ if (sc->sc_provider != NULL)
+ return (sc);
+ if (flags & M_NOWAIT) {
+ sx_xunlock(&sc->sc_lock);
+ return (NULL);
+ }
+
+ /*
+ * This is a dumb hack. G_mirror does not expose any real
+ * wakeup API for observing state changes, and even if it did,
+ * its "RUNNING" state does not actually reflect all softc
+ * elements being initialized.
+ *
+ * Revamping g_mirror to have a 3rd, ACTUALLY_RUNNING state and
+ * updating all assertions and sc_state checks is a large work
+ * and would be easy to introduce regressions.
+ *
+ * Revamping g_mirror to have a wakeup for state changes would
+ * be difficult if one wanted to capture more than just
+ * sc_state and sc_provider.
+ *
+ * For now, just dummy sleep-poll until sc_provider shows up,
+ * the user cancels, or the g_mirror is destroyed.
+ */
+ error = sx_sleep(&sc, &sc->sc_lock, PRIBIO | PCATCH | PDROP,
+ "GM:launched", 1);
+ if (error != 0 && error != EWOULDBLOCK)
+ return (NULL);
+ }
+ __unreachable();
+}
+
static struct g_mirror_disk *
g_mirror_find_disk(struct g_mirror_softc *sc, const char *name)
{
@@ -605,7 +662,7 @@
gctl_error(req, "No 'arg%u' argument.", 0);
return;
}
- sc = g_mirror_find_device(mp, name);
+ sc = g_mirror_find_launched_device(mp, name, M_WAITOK);
if (sc == NULL) {
gctl_error(req, "No such device: %s.", name);
return;
@@ -847,7 +904,7 @@
gctl_error(req, "Invalid '%s' argument.", "size");
return;
}
- sc = g_mirror_find_device(mp, name);
+ sc = g_mirror_find_launched_device(mp, name, M_WAITOK);
if (sc == NULL) {
gctl_error(req, "No such device: %s.", name);
return;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Dec 22, 11:12 PM (11 h, 41 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27142883
Default Alt Text
D24780.id.diff (2 KB)
Attached To
Mode
D24780: geom(4) mirror: Do not panic on gmirror(8) insert, resize
Attached
Detach File
Event Timeline
Log In to Comment