diff options
author | Rich Ercolani <214141+rincebrain@users.noreply.github.com> | 2021-07-26 13:51:30 -0400 |
---|---|---|
committer | Tony Hutter <hutter2@llnl.gov> | 2021-09-22 15:19:08 -0700 |
commit | 05c96b438ab374002e10e9d423fdd903452c4474 (patch) | |
tree | 4273a90b91299da832f377b9420723c2c71356c2 | |
parent | ccf6d0a59bf8ac33b1a4f7df1f88e99a9554d978 (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.c | 9 |
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; } |