aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmeer Hamza <106930537+ixhamza@users.noreply.github.com>2022-11-04 18:33:47 +0000
committerGitHub <noreply@github.com>2022-11-04 18:33:47 +0000
commitc23738c70eb86a7f04f93292caef2ed977047608 (patch)
tree43f66a5db16fdbf4cc460ce379c80aedaad69ff2
parent73b8f700b68dc1c537781b2bee0f06c2b6d09418 (diff)
downloadsrc-c23738c70eb86a7f04f93292caef2ed977047608.tar.gz
src-c23738c70eb86a7f04f93292caef2ed977047608.zip
zed: Prevent special vdev to be replaced by hot spare
Special vdevs should not be replaced by a hot spare. Log vdevs already support this, extending the functionality for special vdevs. Reviewed-by: Ryan Moeller <ryan@iXsystems.com> Reviewed-by: Tony Hutter <hutter2@llnl.gov> Reviewed-by: Richard Yao <richard.yao@alumni.stonybrook.edu> Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Ameer Hamza <ahamza@ixsystems.com> Closes #14129
-rw-r--r--module/zfs/spa.c6
-rwxr-xr-xtests/zfs-tests/tests/functional/fault/auto_offline_001_pos.ksh5
2 files changed, 9 insertions, 2 deletions
diff --git a/module/zfs/spa.c b/module/zfs/spa.c
index de5bbcc09412..fe7051db2737 100644
--- a/module/zfs/spa.c
+++ b/module/zfs/spa.c
@@ -6819,10 +6819,12 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing,
return (spa_vdev_exit(spa, newrootvd, txg, error));
/*
- * Spares can't replace logs
+ * log, dedup and special vdevs should not be replaced by spares.
*/
- if (oldvd->vdev_top->vdev_islog && newvd->vdev_isspare)
+ if ((oldvd->vdev_top->vdev_alloc_bias != VDEV_BIAS_NONE ||
+ oldvd->vdev_top->vdev_islog) && newvd->vdev_isspare) {
return (spa_vdev_exit(spa, newrootvd, txg, ENOTSUP));
+ }
/*
* A dRAID spare can only replace a child of its parent dRAID vdev.
diff --git a/tests/zfs-tests/tests/functional/fault/auto_offline_001_pos.ksh b/tests/zfs-tests/tests/functional/fault/auto_offline_001_pos.ksh
index 0ab9317c0a06..c0387e1d3235 100755
--- a/tests/zfs-tests/tests/functional/fault/auto_offline_001_pos.ksh
+++ b/tests/zfs-tests/tests/functional/fault/auto_offline_001_pos.ksh
@@ -121,6 +121,11 @@ done
# the removed data device
for conf in "${poolconfs[@]}"
do
+ # special vdev can not be replaced by a hot spare
+ if [[ $conf = *"special mirror"* ]]; then
+ continue
+ fi
+
# 1. Create a pool with a spare
log_must zpool create -f $TESTPOOL $conf
block_device_wait ${DEV_DSKDIR}/${removedev}