diff options
author | Justin Hibbits <jhibbits@FreeBSD.org> | 2018-02-13 17:40:09 +0000 |
---|---|---|
committer | Justin Hibbits <jhibbits@FreeBSD.org> | 2018-02-13 17:40:09 +0000 |
commit | 08a3b42fdb4d439298a3bf24cf56003cb349b703 (patch) | |
tree | af9d186891268ed13f90bafbeaaac9bca889499b /sys/geom/part | |
parent | 157f3d764973a807959284721312f5dda2149f8e (diff) | |
download | src-08a3b42fdb4d439298a3bf24cf56003cb349b703.tar.gz src-08a3b42fdb4d439298a3bf24cf56003cb349b703.zip |
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
Notes
Notes:
svn path=/head/; revision=329225
Diffstat (limited to 'sys/geom/part')
-rw-r--r-- | sys/geom/part/g_part.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/sys/geom/part/g_part.c b/sys/geom/part/g_part.c index ae76e10c6578..976ec197fe1c 100644 --- a/sys/geom/part/g_part.c +++ b/sys/geom/part/g_part.c @@ -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); } |