diff options
author | phk <phk@FreeBSD.org> | 2003-11-15 18:44:43 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2003-11-15 18:44:43 +0000 |
commit | 06ab707e796698baced2d1cb5ff031286e34e4cd (patch) | |
tree | cd38352ef4b6228e69f9c5e198d79ed0a455ba5d /sys/geom | |
parent | 1cf4c969195794a9a3d1ea20d5e6fc8aeeeb464c (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/geom/geom_subr.c | 38 |
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 */ |