svn commit: r238868 - head/sys/geom/gate
Mikolaj Golub
trociny at FreeBSD.org
Sat Jul 28 16:30:51 UTC 2012
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
More information about the svn-src-head
mailing list