]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Fix unfortunate NULL in spa_update_dspace
authorRich Ercolani <214141+rincebrain@users.noreply.github.com>
Mon, 26 Jul 2021 17:51:30 +0000 (13:51 -0400)
committerGitHub <noreply@github.com>
Mon, 26 Jul 2021 17:51:30 +0000 (10:51 -0700)
After 1325434b, we can in certain circumstances end up calling
spa_update_dspace with vd->vdev_mg NULL, which ends poorly during
vdev removal.

So let's not do that further space adjustment when we can't.

Reviewed-by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Rich Ercolani <rincebrain@gmail.com>
Closes #12380
Closes #12428

module/zfs/spa_misc.c

index 58039f3d103c05052734bf49610f2cd55691adb3..ad1c4437c098760959638534ba4b736e04726110 100644 (file)
@@ -1853,7 +1853,14 @@ spa_update_dspace(spa_t *spa)
                spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER);
                vdev_t *vd =
                    vdev_lookup_top(spa, spa->spa_vdev_removal->svr_vdev_id);
-               if (vd->vdev_mg->mg_class == spa_normal_class(spa)) {
+               /*
+                * If the stars align, we can wind up here after
+                * vdev_remove_complete() has cleared vd->vdev_mg but before
+                * spa->spa_vdev_removal gets cleared, so we must check before
+                * we dereference.
+                */
+               if (vd->vdev_mg &&
+                   vd->vdev_mg->mg_class == spa_normal_class(spa)) {
                        spa->spa_dspace -= spa_deflate(spa) ?
                            vd->vdev_stat.vs_dspace : vd->vdev_stat.vs_space;
                }