svn commit: r220300 - stable/8/sys/geom/gate
Mikolaj Golub
trociny at FreeBSD.org
Sun Apr 3 18:56:17 UTC 2011
Author: trociny
Date: Sun Apr 3 18:56:16 2011
New Revision: 220300
URL: http://svn.freebsd.org/changeset/base/220300
Log:
MFC r220062, r220173:
r220062:
In g_gate_create() there is a window between when g_gate_softc is
registered in g_gate_units array and when its sc_provider field is
filled. If during this period g_gate_units is accessed by another
thread that is checking for provider name collision the crash is
possible.
Fix this by adding sc_name field to struct g_gate_softc. In
g_gate_create() when g_gate_softc is created but sc_provider is still
not sc_name points to provider name stored in the local array.
Reported by: Freddie Cash <fjwcash at gmail.com>
r220173:
Increase debug level on g_gate device destruction and add message on
device creation.
Suggested by: danger
Approved by: pjd (mentor)
Modified:
stable/8/sys/geom/gate/g_gate.c
stable/8/sys/geom/gate/g_gate.h
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
Modified: stable/8/sys/geom/gate/g_gate.c
==============================================================================
--- stable/8/sys/geom/gate/g_gate.c Sun Apr 3 17:38:12 2011 (r220299)
+++ stable/8/sys/geom/gate/g_gate.c Sun Apr 3 18:56:16 2011 (r220300)
@@ -134,7 +134,7 @@ g_gate_destroy(struct g_gate_softc *sc,
mtx_unlock(&g_gate_units_lock);
mtx_destroy(&sc->sc_queue_mtx);
g_topology_lock();
- G_GATE_DEBUG(0, "Device %s destroyed.", gp->name);
+ G_GATE_DEBUG(1, "Device %s destroyed.", gp->name);
gp->softc = NULL;
g_wither_geom(gp, ENXIO);
sc->sc_provider = NULL;
@@ -407,13 +407,14 @@ g_gate_create(struct g_gate_ctl_create *
for (unit = 0; unit < g_gate_maxunits; unit++) {
if (g_gate_units[unit] == NULL)
continue;
- if (strcmp(name, g_gate_units[unit]->sc_provider->name) != 0)
+ if (strcmp(name, g_gate_units[unit]->sc_name) != 0)
continue;
mtx_unlock(&g_gate_units_lock);
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);
@@ -432,6 +433,10 @@ g_gate_create(struct g_gate_ctl_create *
sc->sc_provider = pp;
g_error_provider(pp, 0);
g_topology_unlock();
+ mtx_lock(&g_gate_units_lock);
+ sc->sc_name = sc->sc_provider->name;
+ mtx_unlock(&g_gate_units_lock);
+ G_GATE_DEBUG(1, "Device %s created.", gp->name);
if (sc->sc_timeout > 0) {
callout_reset(&sc->sc_callout, sc->sc_timeout * hz,
Modified: stable/8/sys/geom/gate/g_gate.h
==============================================================================
--- stable/8/sys/geom/gate/g_gate.h Sun Apr 3 17:38:12 2011 (r220299)
+++ stable/8/sys/geom/gate/g_gate.h Sun Apr 3 18:56:16 2011 (r220300)
@@ -76,6 +76,7 @@
* 'P:' means 'Protected by'.
*/
struct g_gate_softc {
+ char *sc_name; /* P: (read-only) */
int sc_unit; /* P: (read-only) */
int sc_ref; /* P: g_gate_list_mtx */
struct g_provider *sc_provider; /* P: (read-only) */
@@ -96,7 +97,6 @@ struct g_gate_softc {
LIST_ENTRY(g_gate_softc) sc_next; /* P: g_gate_list_mtx */
char sc_info[G_GATE_INFOSIZE]; /* P: (read-only) */
};
-#define sc_name sc_provider->geom->name
#define G_GATE_DEBUG(lvl, ...) do { \
if (g_gate_debug >= (lvl)) { \
More information about the svn-src-all
mailing list