Date: Mon, 25 Jan 2016 09:29:29 +0000 (UTC) From: Steven Hartland <smh@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r294709 - stable/10/sys/geom/multipath Message-ID: <201601250929.u0P9TTZH026683@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: smh Date: Mon Jan 25 09:29:29 2016 New Revision: 294709 URL: https://svnweb.freebsd.org/changeset/base/294709 Log: MFC r292289: Prevent g_access calls to bad multipath members Sponsored by: Multiplay Modified: stable/10/sys/geom/multipath/g_multipath.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/geom/multipath/g_multipath.c ============================================================================== --- stable/10/sys/geom/multipath/g_multipath.c Mon Jan 25 09:26:23 2016 (r294708) +++ stable/10/sys/geom/multipath/g_multipath.c Mon Jan 25 09:29:29 2016 (r294709) @@ -107,8 +107,9 @@ struct g_class g_multipath_class = { #define MP_NEW 0x00000004 #define MP_POSTED 0x00000008 #define MP_BAD (MP_FAIL | MP_LOST | MP_NEW) -#define MP_IDLE 0x00000010 -#define MP_IDLE_MASK 0xfffffff0 +#define MP_WITHER 0x00000010 +#define MP_IDLE 0x00000020 +#define MP_IDLE_MASK 0xffffffe0 static int g_multipath_good(struct g_geom *gp) @@ -204,6 +205,7 @@ g_mpd(void *arg, int flags __unused) g_access(cp, -cp->acr, -cp->acw, -cp->ace); if (w > 0 && cp->provider != NULL && (cp->provider->geom->flags & G_GEOM_WITHER) == 0) { + cp->index |= MP_WITHER; g_post_event(g_mpd, cp, M_WAITOK, NULL); return; } @@ -467,23 +469,37 @@ g_multipath_access(struct g_provider *pp gp = pp->geom; + /* Error used if we have no valid consumers. */ + error = ENXIO; + LIST_FOREACH(cp, &gp->consumer, consumer) { + if (cp->index & MP_WITHER) + continue; + error = g_access(cp, dr, dw, de); if (error) { badcp = cp; goto fail; } } + + if (error != 0) + return (error); + sc = gp->softc; sc->sc_opened += dr + dw + de; if (sc->sc_stopping && sc->sc_opened == 0) g_multipath_destroy(gp); + return (0); fail: LIST_FOREACH(cp, &gp->consumer, consumer) { if (cp == badcp) break; + if (cp->index & MP_WITHER) + continue; + (void) g_access(cp, -dr, -dw, -de); } return (error);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201601250929.u0P9TTZH026683>