summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRich Ercolani <214141+rincebrain@users.noreply.github.com>2021-07-26 13:51:30 -0400
committerTony Hutter <hutter2@llnl.gov>2021-09-22 15:19:08 -0700
commit05c96b438ab374002e10e9d423fdd903452c4474 (patch)
tree4273a90b91299da832f377b9420723c2c71356c2
parentccf6d0a59bf8ac33b1a4f7df1f88e99a9554d978 (diff)
Fix unfortunate NULL in spa_update_dspace
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
-rw-r--r--module/zfs/spa_misc.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/module/zfs/spa_misc.c b/module/zfs/spa_misc.c
index 25502f769..799670bb1 100644
--- a/module/zfs/spa_misc.c
+++ b/module/zfs/spa_misc.c
@@ -1849,7 +1849,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;
}