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