PERFORCE change 112505 for review
Matt Jacob
mjacob at FreeBSD.org
Thu Jan 4 16:26:33 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=112505
Change 112505 by mjacob at mjexp on 2007/01/05 00:25:37
A little more tweaking on this toy to finally get it to completely
clean out dead consumers via posting events.
Affected files ...
.. //depot/projects/mjexp/sys/geom/multipath/g_multipath.c#10 edit
.. //depot/projects/mjexp/sys/geom/multipath/g_multipath.h#5 edit
Differences ...
==== //depot/projects/mjexp/sys/geom/multipath/g_multipath.c#10 (text+ko) ====
@@ -74,6 +74,7 @@
static void
g_multipath_orphan(struct g_consumer *cp)
{
+printf("%s called on %s\n", __FUNCTION__, cp->provider? cp->provider->name : "none");
g_topology_assert();
g_multipath_destroy(cp->geom);
}
@@ -104,6 +105,17 @@
}
static void
+g_mpd(void *arg, int flags __unused)
+{
+ struct g_consumer *cp;
+ g_topology_assert();
+ cp = arg;
+ g_access(cp, -cp->acr, -cp->acw, -cp->ace);
+ g_detach(cp);
+ g_destroy_consumer(cp);
+}
+
+static void
g_multipath_done(struct bio *bp)
{
struct bio *pbp = bp->bio_parent;
@@ -131,6 +143,8 @@
if (dofail) {
struct g_consumer *cp = bp->bio_from;
+ struct g_consumer *lcp;
+ struct g_provider *pp = cp->provider;
/*
* If we had a failure, we have to check first to see
@@ -139,31 +153,44 @@
* a number of failures). If so, we then switch consumers
* to the next available consumer.
*/
+ g_topology_lock();
if (cp == sc->cp_active) {
- printf("i/o failure is causing detach of %s from %s\n",
- cp->provider->name, gp->name);
-/*
- * XXX: The following two lines are probably wrong due to inflights
- */
- g_detach(cp);
- g_destroy_consumer(cp);
- sc->cp_active = LIST_FIRST(&gp->consumer);
+ printf("GEOM_MULTIPATH: I/O failure terminates use of "
+ "%s in %s\n", cp->provider->name, gp->name);
+ cp->index = 1;
+ sc->cp_active = NULL;
+ LIST_FOREACH(lcp, &gp->consumer, consumer) {
+ if (lcp->index == 0) {
+ sc->cp_active = lcp;
+ break;
+ }
+ }
+ if (sc->cp_active == NULL) {
+ printf("GEOM_MULTIPATH: out of providers\n");
+ g_topology_unlock();
+ goto out;
+ }
+ printf("GEOM_MULTIPATH: switching to provider %s\n",
+ sc->cp_active->provider->name);
+ }
+ g_topology_unlock();
+ if (cp->nend == cp->nstart && pp->nend == pp->nstart) {
+ printf("GEOM_MULTIPATH: old provider %s is now quiet\n",
+ pp->name);
+ g_post_event(g_mpd, cp, M_NOWAIT, NULL);
}
/*
* If we can fruitfully restart the I/O, do so.
*/
if (sc->cp_active) {
- printf("switching to provider %s\n",
- sc->cp_active->provider->name);
g_destroy_bio(bp);
pbp->bio_children--;
g_multipath_start(pbp);
return;
- } else {
- printf("out of providers to try\n");
}
}
+out:
g_std_done(bp);
}
@@ -275,7 +302,7 @@
return (error);
}
cp->private = sc;
- cp->index = sc->index++;
+ cp->index = 0;
/*
* Set access permissions on new consumer to match other consumers
@@ -375,7 +402,6 @@
g_destroy_consumer(cp);
g_destroy_geom(gp);
if (error != 0) {
- printf("%s had error %d reading metadata\n", pp->name, error);
return (NULL);
}
gp = NULL;
==== //depot/projects/mjexp/sys/geom/multipath/g_multipath.h#5 (text+ko) ====
@@ -47,7 +47,6 @@
struct g_consumer * cp_active;
char sc_name[16];
char sc_uuid[40];
- int index;
};
#endif /* _KERNEL */
More information about the p4-projects
mailing list