svn commit: r294709 - stable/10/sys/geom/multipath

Steven Hartland smh at FreeBSD.org
Mon Jan 25 09:29:31 UTC 2016


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);


More information about the svn-src-all mailing list