Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 28 Jul 2012 16:30:50 +0000 (UTC)
From:      Mikolaj Golub <trociny@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r238868 - head/sys/geom/gate
Message-ID:  <201207281630.q6SGUosQ046201@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trociny
Date: Sat Jul 28 16:30:50 2012
New Revision: 238868
URL: http://svn.freebsd.org/changeset/base/238868

Log:
  Reorder things in g_gate_create() so at the moment when g_new_geomf()
  is called name is properly initialized.
  
  Discussed with:	pjd
  MFC after:	2 weeks

Modified:
  head/sys/geom/gate/g_gate.c

Modified: head/sys/geom/gate/g_gate.c
==============================================================================
--- head/sys/geom/gate/g_gate.c	Sat Jul 28 15:13:48 2012	(r238867)
+++ head/sys/geom/gate/g_gate.c	Sat Jul 28 16:30:50 2012	(r238868)
@@ -470,6 +470,44 @@ g_gate_create(struct g_gate_ctl_create *
 		return (EINVAL);
 	}
 
+	sc = malloc(sizeof(*sc), M_GATE, M_WAITOK | M_ZERO);
+	sc->sc_flags = (ggio->gctl_flags & G_GATE_USERFLAGS);
+	strlcpy(sc->sc_info, ggio->gctl_info, sizeof(sc->sc_info));
+	sc->sc_seq = 1;
+	bioq_init(&sc->sc_inqueue);
+	bioq_init(&sc->sc_outqueue);
+	mtx_init(&sc->sc_queue_mtx, "gg:queue", NULL, MTX_DEF);
+	sc->sc_queue_count = 0;
+	sc->sc_queue_size = ggio->gctl_maxcount;
+	if (sc->sc_queue_size > G_GATE_MAX_QUEUE_SIZE)
+		sc->sc_queue_size = G_GATE_MAX_QUEUE_SIZE;
+	sc->sc_timeout = ggio->gctl_timeout;
+	callout_init(&sc->sc_callout, CALLOUT_MPSAFE);
+
+	mtx_lock(&g_gate_units_lock);
+	sc->sc_unit = g_gate_getunit(ggio->gctl_unit, &error);
+	if (sc->sc_unit < 0)
+		goto fail1;
+	if (ggio->gctl_unit == G_GATE_NAME_GIVEN)
+		snprintf(name, sizeof(name), "%s", ggio->gctl_name);
+	else {
+		snprintf(name, sizeof(name), "%s%d", G_GATE_PROVIDER_NAME,
+		    sc->sc_unit);
+	}
+	/* Check for name collision. */
+	for (unit = 0; unit < g_gate_maxunits; unit++) {
+		if (g_gate_units[unit] == NULL)
+			continue;
+		if (strcmp(name, g_gate_units[unit]->sc_name) != 0)
+			continue;
+		error = EEXIST;
+		goto fail1;
+	}
+	sc->sc_name = name;
+	g_gate_units[sc->sc_unit] = sc;
+	g_gate_nunits++;
+	mtx_unlock(&g_gate_units_lock);
+
 	g_topology_lock();
 
 	if (ggio->gctl_readprov[0] == '\0') {
@@ -477,38 +515,24 @@ g_gate_create(struct g_gate_ctl_create *
 	} else {
 		ropp = g_provider_by_name(ggio->gctl_readprov);
 		if (ropp == NULL) {
-			g_topology_unlock();
 			G_GATE_DEBUG(1, "Provider %s doesn't exist.",
 			    ggio->gctl_readprov);
-			return (EINVAL);
+			error = EINVAL;
+			goto fail2;
 		}
 		if ((ggio->gctl_readoffset % ggio->gctl_sectorsize) != 0) {
-			g_topology_unlock();
 			G_GATE_DEBUG(1, "Invalid read offset.");
-			return (EINVAL);
+			error = EINVAL;
+			goto fail2;
 		}
 		if (ggio->gctl_mediasize + ggio->gctl_readoffset >
 		    ropp->mediasize) {
-			g_topology_unlock();
 			G_GATE_DEBUG(1, "Invalid read offset or media size.");
-			return (EINVAL);
+			error = EINVAL;
+			goto fail2;
 		}
 	}
 
-	sc = malloc(sizeof(*sc), M_GATE, M_WAITOK | M_ZERO);
-	sc->sc_flags = (ggio->gctl_flags & G_GATE_USERFLAGS);
-	strlcpy(sc->sc_info, ggio->gctl_info, sizeof(sc->sc_info));
-	sc->sc_seq = 1;
-	bioq_init(&sc->sc_inqueue);
-	bioq_init(&sc->sc_outqueue);
-	mtx_init(&sc->sc_queue_mtx, "gg:queue", NULL, MTX_DEF);
-	sc->sc_queue_count = 0;
-	sc->sc_queue_size = ggio->gctl_maxcount;
-	if (sc->sc_queue_size > G_GATE_MAX_QUEUE_SIZE)
-		sc->sc_queue_size = G_GATE_MAX_QUEUE_SIZE;
-	sc->sc_timeout = ggio->gctl_timeout;
-	callout_init(&sc->sc_callout, CALLOUT_MPSAFE);
-
 	gp = g_new_geomf(&g_gate_class, "%s", name);
 	gp->start = g_gate_start;
 	gp->access = g_gate_access;
@@ -521,70 +545,18 @@ g_gate_create(struct g_gate_ctl_create *
 		error = g_attach(cp, ropp);
 		if (error != 0) {
 			G_GATE_DEBUG(1, "Unable to attach to %s.", ropp->name);
-		} else {
-			error = g_access(cp, 1, 0, 0);
-			if (error != 0) {
-				G_GATE_DEBUG(1, "Unable to access %s.",
-				    ropp->name);
-				g_detach(cp);
-			}
+			goto fail3;
 		}
+		error = g_access(cp, 1, 0, 0);
 		if (error != 0) {
-			g_destroy_consumer(cp);
-			g_destroy_geom(gp);
-			g_topology_unlock();
-			mtx_destroy(&sc->sc_queue_mtx);
-			free(sc, M_GATE);
-			return (error);
+			G_GATE_DEBUG(1, "Unable to access %s.", ropp->name);
+			g_detach(cp);
+			goto fail3;
 		}
 		sc->sc_readcons = cp;
 		sc->sc_readoffset = ggio->gctl_readoffset;
 	}
 
-	mtx_lock(&g_gate_units_lock);
-	sc->sc_unit = g_gate_getunit(ggio->gctl_unit, &error);
-	if (sc->sc_unit < 0) {
-		mtx_unlock(&g_gate_units_lock);
-		if (sc->sc_readcons != NULL) {
-			(void)g_access(sc->sc_readcons, -1, 0, 0);
-			g_detach(sc->sc_readcons);
-			g_destroy_consumer(sc->sc_readcons);
-		}
-		g_destroy_geom(gp);
-		g_topology_unlock();
-		mtx_destroy(&sc->sc_queue_mtx);
-		free(sc, M_GATE);
-		return (error);
-	}
-	if (ggio->gctl_unit == G_GATE_NAME_GIVEN)
-		snprintf(name, sizeof(name), "%s", ggio->gctl_name);
-	else {
-		snprintf(name, sizeof(name), "%s%d", G_GATE_PROVIDER_NAME,
-		    sc->sc_unit);
-	}
-	/* Check for name collision. */
-	for (unit = 0; unit < g_gate_maxunits; unit++) {
-		if (g_gate_units[unit] == NULL)
-			continue;
-		if (strcmp(name, g_gate_units[unit]->sc_name) != 0)
-			continue;
-		mtx_unlock(&g_gate_units_lock);
-		if (sc->sc_readcons != NULL) {
-			(void)g_access(sc->sc_readcons, -1, 0, 0);
-			g_detach(sc->sc_readcons);
-			g_destroy_consumer(sc->sc_readcons);
-		}
-		g_destroy_geom(gp);
-		g_topology_unlock();
-		mtx_destroy(&sc->sc_queue_mtx);
-		free(sc, M_GATE);
-		return (EEXIST);
-	}
-	sc->sc_name = name;
-	g_gate_units[sc->sc_unit] = sc;
-	g_gate_nunits++;
-	mtx_unlock(&g_gate_units_lock);
-
 	ggio->gctl_unit = sc->sc_unit;
 
 	pp = g_new_providerf(gp, "%s", name);
@@ -604,6 +576,20 @@ g_gate_create(struct g_gate_ctl_create *
 		    g_gate_guard, sc);
 	}
 	return (0);
+fail3:
+	g_destroy_consumer(cp);
+	g_destroy_geom(gp);
+fail2:
+	g_topology_unlock();
+	mtx_lock(&g_gate_units_lock);
+	g_gate_units[sc->sc_unit] = NULL;
+	KASSERT(g_gate_nunits > 0, ("negative g_gate_nunits?"));
+	g_gate_nunits--;
+fail1:
+	mtx_unlock(&g_gate_units_lock);
+	mtx_destroy(&sc->sc_queue_mtx);
+	free(sc, M_GATE);
+	return (error);
 }
 
 static int



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207281630.q6SGUosQ046201>