summaryrefslogtreecommitdiffstats
path: root/sys/geom/geom_subr.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>2003-11-15 18:44:43 +0000
committerphk <phk@FreeBSD.org>2003-11-15 18:44:43 +0000
commit06ab707e796698baced2d1cb5ff031286e34e4cd (patch)
treecd38352ef4b6228e69f9c5e198d79ed0a455ba5d /sys/geom/geom_subr.c
parent1cf4c969195794a9a3d1ea20d5e6fc8aeeeb464c (diff)
downloadFreeBSD-src-06ab707e796698baced2d1cb5ff031286e34e4cd.zip
FreeBSD-src-06ab707e796698baced2d1cb5ff031286e34e4cd.tar.gz
This is a crude bandaid for 5.2 to protect against providers which disappear
while being tasted. I can moderately easy trigger this with atapi-cd, but I do not fully understand the circumstances.
Diffstat (limited to 'sys/geom/geom_subr.c')
-rw-r--r--sys/geom/geom_subr.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c
index 4ec32cb..f2f8820 100644
--- a/sys/geom/geom_subr.c
+++ b/sys/geom/geom_subr.c
@@ -57,6 +57,7 @@ struct class_list_head g_classes = LIST_HEAD_INITIALIZER(g_classes);
static struct g_tailq_head geoms = TAILQ_HEAD_INITIALIZER(geoms);
char *g_wait_event, *g_wait_up, *g_wait_down, *g_wait_sim;
+static int g_valid_obj(void const *ptr);
struct g_hh00 {
struct g_class *mp;
@@ -343,6 +344,14 @@ g_new_provider_event(void *arg, int flag)
continue;
mp->taste(mp, pp, 0);
g_topology_assert();
+ /*
+ * XXX: Bandaid for 5.2-RELEASE
+ * XXX: DO NOT REPLICATE THIS CODE!
+ */
+ if (!g_valid_obj(pp)) {
+ printf("g_provider %p disappeared while tasting\n", pp);
+ return;
+ }
}
}
@@ -783,6 +792,35 @@ g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len)
}
/*
+ * XXX: Bandaid for 5.2.
+ * XXX: DO NOT EVEN THINK ABOUT CALLING THIS FUNCTION!
+ */
+static int
+g_valid_obj(void const *ptr)
+{
+ struct g_class *mp;
+ struct g_geom *gp;
+ struct g_consumer *cp;
+ struct g_provider *pp;
+
+ LIST_FOREACH(mp, &g_classes, class) {
+ if (ptr == mp)
+ return (1);
+ LIST_FOREACH(gp, &mp->geom, geom) {
+ if (ptr == gp)
+ return (1);
+ LIST_FOREACH(cp, &gp->consumer, consumer)
+ if (ptr == cp)
+ return (1);
+ LIST_FOREACH(pp, &gp->provider, provider)
+ if (ptr == pp)
+ return (1);
+ }
+ }
+ return(0);
+}
+
+/*
* Check if the given pointer is a live object
*/
OpenPOWER on IntegriCloud