From c12b59d59693a174a3c8dc57dadfe609594bf6e9 Mon Sep 17 00:00:00 2001 From: Don Brady Date: Mon, 12 Oct 2020 17:34:40 -0600 Subject: [PATCH 1/2] Ignore special vdev ashift for spa ashift min/max Signed-off-by: Don Brady --- module/zfs/vdev.c | 18 +++--------------- module/zfs/vdev_removal.c | 25 +++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c index a94101485c94..6af61cdcd9bf 100644 --- a/module/zfs/vdev.c +++ b/module/zfs/vdev.c @@ -1286,9 +1286,9 @@ vdev_metaslab_group_create(vdev_t *vd) spa->spa_alloc_count); /* - * The spa ashift values currently only reflect the - * general vdev classes. Class destination is late - * binding so ashift checking had to wait until now + * The spa ashift min/max only apply for the normal metaslab + * class. Class destination is late binding so ashift boundry + * setting had to wait until now. */ if (vd->vdev_top == vd && vd->vdev_ashift != 0 && mc == spa_normal_class(spa) && vd->vdev_aux == NULL) { @@ -1952,18 +1952,6 @@ vdev_open(vdev_t *vd) return (error); } - /* - * Track the min and max ashift values for normal data devices. - */ - if (vd->vdev_top == vd && vd->vdev_ashift != 0 && - vd->vdev_alloc_bias == VDEV_BIAS_NONE && - vd->vdev_islog == 0 && vd->vdev_aux == NULL) { - if (vd->vdev_ashift > spa->spa_max_ashift) - spa->spa_max_ashift = vd->vdev_ashift; - if (vd->vdev_ashift < spa->spa_min_ashift) - spa->spa_min_ashift = vd->vdev_ashift; - } - /* * If this is a leaf vdev, assess whether a resilver is needed. * But don't do this if we are doing a reopen for a scrub, since diff --git a/module/zfs/vdev_removal.c b/module/zfs/vdev_removal.c index fdeca7ab3418..5b5d442e5068 100644 --- a/module/zfs/vdev_removal.c +++ b/module/zfs/vdev_removal.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, 2019 by Delphix. All rights reserved. + * Copyright (c) 2011, 2020 by Delphix. All rights reserved. * Copyright (c) 2019, loli10K . All rights reserved. */ @@ -2030,6 +2030,14 @@ spa_vdev_remove_top_check(vdev_t *vd) return (SET_ERROR(EINVAL)); } + /* + * A removed special/dedup vdev must have same ashift as normal class. + */ + if (vd->vdev_alloc_bias != VDEV_BIAS_NONE && !vd->vdev_islog && + vd->vdev_ashift != spa->spa_max_ashift) { + return (SET_ERROR(EINVAL)); + } + /* * All vdevs in normal class must have the same ashift * and not be raidz. @@ -2038,7 +2046,20 @@ spa_vdev_remove_top_check(vdev_t *vd) int num_indirect = 0; for (uint64_t id = 0; id < rvd->vdev_children; id++) { vdev_t *cvd = rvd->vdev_child[id]; - if (cvd->vdev_ashift != 0 && !cvd->vdev_islog) + + /* + * A removed special/dedup vdev must have the same ashift + * across all vdevs in its class. + */ + if (cvd->vdev_alloc_bias != VDEV_BIAS_NONE && + !cvd->vdev_islog) { + if (cvd->vdev_alloc_bias == vd->vdev_alloc_bias && + cvd->vdev_ashift != vd->vdev_ashift) { + return (SET_ERROR(EINVAL)); + } + } + if (cvd->vdev_ashift != 0 && + cvd->vdev_alloc_bias == VDEV_BIAS_NONE) ASSERT3U(cvd->vdev_ashift, ==, spa->spa_max_ashift); if (cvd->vdev_ops == &vdev_indirect_ops) num_indirect++; From b24b3a7a71809dc86ef3b4ede6ea51a987da4503 Mon Sep 17 00:00:00 2001 From: Don Brady Date: Wed, 14 Oct 2020 12:05:10 -0600 Subject: [PATCH 2/2] Address review feedback. Signed-off-by: Don Brady --- module/zfs/vdev_removal.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/module/zfs/vdev_removal.c b/module/zfs/vdev_removal.c index 5b5d442e5068..ed7d1d4b3030 100644 --- a/module/zfs/vdev_removal.c +++ b/module/zfs/vdev_removal.c @@ -2033,7 +2033,8 @@ spa_vdev_remove_top_check(vdev_t *vd) /* * A removed special/dedup vdev must have same ashift as normal class. */ - if (vd->vdev_alloc_bias != VDEV_BIAS_NONE && !vd->vdev_islog && + ASSERT(!vd->vdev_islog); + if (vd->vdev_alloc_bias != VDEV_BIAS_NONE && vd->vdev_ashift != spa->spa_max_ashift) { return (SET_ERROR(EINVAL)); } @@ -2051,12 +2052,10 @@ spa_vdev_remove_top_check(vdev_t *vd) * A removed special/dedup vdev must have the same ashift * across all vdevs in its class. */ - if (cvd->vdev_alloc_bias != VDEV_BIAS_NONE && - !cvd->vdev_islog) { - if (cvd->vdev_alloc_bias == vd->vdev_alloc_bias && - cvd->vdev_ashift != vd->vdev_ashift) { - return (SET_ERROR(EINVAL)); - } + if (vd->vdev_alloc_bias != VDEV_BIAS_NONE && + cvd->vdev_alloc_bias == vd->vdev_alloc_bias && + cvd->vdev_ashift != vd->vdev_ashift) { + return (SET_ERROR(EINVAL)); } if (cvd->vdev_ashift != 0 && cvd->vdev_alloc_bias == VDEV_BIAS_NONE)