svn commit: r329225 - head/sys/geom/part
Justin Hibbits
jhibbits at FreeBSD.org
Tue Feb 13 17:40:10 UTC 2018
Author: jhibbits
Date: Tue Feb 13 17:40:09 2018
New Revision: 329225
URL: https://svnweb.freebsd.org/changeset/base/329225
Log:
Narrow a race, and fix a leak, in g_part_wither
A race in g_part_wither() can lead to I/O being performed with a freed GEOM
when the device disappears. Close the race as best as we can for now,
following the code patterns from g_part_ctl_destroy() and g_part_ctl_undo().
This also fixes a leak, as g_wither_geom() does not wither providers, it
only orphans them, so the partition entries would never get destroyed in
g_wither_washer().
Note, this is not a complete fix, it can still race with g_part_start(), the
race has merely been narrowed.
Reviewed by: markj
Sponsored by: Dell EMC Isilon
Modified:
head/sys/geom/part/g_part.c
Modified: head/sys/geom/part/g_part.c
==============================================================================
--- head/sys/geom/part/g_part.c Tue Feb 13 17:38:08 2018 (r329224)
+++ head/sys/geom/part/g_part.c Tue Feb 13 17:40:09 2018 (r329225)
@@ -1541,18 +1541,21 @@ g_part_wither(struct g_geom *gp, int error)
{
struct g_part_entry *entry;
struct g_part_table *table;
+ struct g_provider *pp;
table = gp->softc;
if (table != NULL) {
- G_PART_DESTROY(table, NULL);
+ gp->softc = NULL;
while ((entry = LIST_FIRST(&table->gpt_entry)) != NULL) {
LIST_REMOVE(entry, gpe_entry);
+ pp = entry->gpe_pp;
+ entry->gpe_pp->private = NULL;
+ entry->gpe_pp = NULL;
+ g_wither_provider(pp, error);
g_free(entry);
}
- if (gp->softc != NULL) {
- kobj_delete((kobj_t)gp->softc, M_GEOM);
- gp->softc = NULL;
- }
+ G_PART_DESTROY(table, NULL);
+ kobj_delete((kobj_t)table, M_GEOM);
}
g_wither_geom(gp, error);
}
More information about the svn-src-head
mailing list