From f1ca7999bbf2f1c39e80cee176ba52fcca12ec05 Mon Sep 17 00:00:00 2001 From: Rich Ercolani <214141+rincebrain@users.noreply.github.com> Date: Mon, 26 Jul 2021 13:51:30 -0400 Subject: [PATCH] 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 Reviewed-by: Brian Behlendorf Signed-off-by: Rich Ercolani Closes #12380 Closes #12428 --- module/zfs/spa_misc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/module/zfs/spa_misc.c b/module/zfs/spa_misc.c index 58039f3d10..ad1c4437c0 100644 --- a/module/zfs/spa_misc.c +++ b/module/zfs/spa_misc.c @@ -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; }