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);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to