Author: mav
Date: Fri Oct 12 16:55:28 2018
New Revision: 339335
URL: https://svnweb.freebsd.org/changeset/base/339335

Log:
  Avoid zero-sized kmem_alloc() in vdev_compact_children().
  
  The device evacuation code adds a dependency that
  vdev_compact_children() be able to properly empty the vdev_child
  array by setting it to NULL and zeroing vdev_children.  Under Linux,
  kmem_alloc() and related functions return a sentinel pointer rather
  than NULL for zero-sized allocations.
  
  This is a part of ZoL port of device removal patch:
  
  commit a1d477c24c7badc89c60955995fd84d311938486
  Author: Matthew Ahrens <mahr...@delphix.com>
  Ported-by: Tim Chase <t...@chase2k.com>
  
  Approved by:  re (kib)
  MFC after:    1 week

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c  Fri Oct 12 
16:24:49 2018        (r339334)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c  Fri Oct 12 
16:55:28 2018        (r339335)
@@ -505,17 +505,24 @@ vdev_compact_children(vdev_t *pvd)
 
        ASSERT(spa_config_held(pvd->vdev_spa, SCL_ALL, RW_WRITER) == SCL_ALL);
 
+       if (oldc == 0)
+               return;
+
        for (int c = newc = 0; c < oldc; c++)
                if (pvd->vdev_child[c])
                        newc++;
 
-       newchild = kmem_alloc(newc * sizeof (vdev_t *), KM_SLEEP);
+       if (newc > 0) {
+               newchild = kmem_alloc(newc * sizeof (vdev_t *), KM_SLEEP);
 
-       for (int c = newc = 0; c < oldc; c++) {
-               if ((cvd = pvd->vdev_child[c]) != NULL) {
-                       newchild[newc] = cvd;
-                       cvd->vdev_id = newc++;
+               for (int c = newc = 0; c < oldc; c++) {
+                       if ((cvd = pvd->vdev_child[c]) != NULL) {
+                               newchild[newc] = cvd;
+                               cvd->vdev_id = newc++;
+                       }
                }
+       } else {
+               newchild = NULL;
        }
 
        kmem_free(pvd->vdev_child, oldc * sizeof (vdev_t *));
_______________________________________________
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