diff options
author | thomas <thomas@FreeBSD.org> | 2012-08-25 10:36:31 +0000 |
---|---|---|
committer | thomas <thomas@FreeBSD.org> | 2012-08-25 10:36:31 +0000 |
commit | d5129fde3c8f2b0e1d85049892dbcc47bd1be041 (patch) | |
tree | fed304e9abf5edc3bb5baa136f10acddcb69bd4d /sys/geom | |
parent | 4952c1e53e5666c79737ca683e5e9594f39dda7a (diff) | |
download | FreeBSD-src-d5129fde3c8f2b0e1d85049892dbcc47bd1be041.zip FreeBSD-src-d5129fde3c8f2b0e1d85049892dbcc47bd1be041.tar.gz |
(g_multipath_rotate): Fix algorithm so that it does rotate over all good
providers, not just the last two.
PR: kern/170379
Reviewed by: mav
MFC after: 2 weeks
Diffstat (limited to 'sys/geom')
-rw-r--r-- | sys/geom/multipath/g_multipath.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/sys/geom/multipath/g_multipath.c b/sys/geom/multipath/g_multipath.c index b50367e..7ca0082 100644 --- a/sys/geom/multipath/g_multipath.c +++ b/sys/geom/multipath/g_multipath.c @@ -590,19 +590,26 @@ g_multipath_destroy_geom(struct gctl_req *req, struct g_class *mp, static int g_multipath_rotate(struct g_geom *gp) { - struct g_consumer *lcp; + struct g_consumer *lcp, *first_good_cp = NULL; struct g_multipath_softc *sc = gp->softc; + int active_cp_seen = 0; g_topology_assert(); if (sc == NULL) return (ENXIO); LIST_FOREACH(lcp, &gp->consumer, consumer) { if ((lcp->index & MP_BAD) == 0) { - if (sc->sc_active != lcp) + if (first_good_cp == NULL) + first_good_cp = lcp; + if (active_cp_seen) break; } + if (sc->sc_active == lcp) + active_cp_seen = 1; } - if (lcp) { + if (lcp == NULL) + lcp = first_good_cp; + if (lcp && lcp != sc->sc_active) { sc->sc_active = lcp; if (sc->sc_active_active != 1) printf("GEOM_MULTIPATH: %s is now active path in %s\n", |