Skip to content

Commit b3f4436

Browse files
Don Bradybehlendorf
Don Brady
authored andcommitted
Ignore special vdev ashift for spa ashift min/max
The removal of a vdev in the normal class would fail if there was a special or deup vdev that had a different ashift than the vdevs in the normal class. Moved the initialization of spa_min_ashift / spa_max_ashift from vdev_open so that it occurs after the vdev allocation bias was initialized (i.e. after vdev_load). Caveat -- In order to remove a special/dedup vdev it must have the same ashift as the normal pool vdevs. This could perhaps be lifted in the future (i.e. for the case where there is ample space in any surviving special class vdevs) Reviewed-by: Matthew Ahrens <mahrens@delphix.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Don Brady <don.brady@delphix.com> Closes #9363 Closes #9364 Closes #11053
1 parent 05f8be3 commit b3f4436

File tree

2 files changed

+25
-17
lines changed

2 files changed

+25
-17
lines changed

module/zfs/vdev.c

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,9 +1286,9 @@ vdev_metaslab_group_create(vdev_t *vd)
12861286
spa->spa_alloc_count);
12871287

12881288
/*
1289-
* The spa ashift values currently only reflect the
1290-
* general vdev classes. Class destination is late
1291-
* binding so ashift checking had to wait until now
1289+
* The spa ashift min/max only apply for the normal metaslab
1290+
* class. Class destination is late binding so ashift boundry
1291+
* setting had to wait until now.
12921292
*/
12931293
if (vd->vdev_top == vd && vd->vdev_ashift != 0 &&
12941294
mc == spa_normal_class(spa) && vd->vdev_aux == NULL) {
@@ -1952,18 +1952,6 @@ vdev_open(vdev_t *vd)
19521952
return (error);
19531953
}
19541954

1955-
/*
1956-
* Track the min and max ashift values for normal data devices.
1957-
*/
1958-
if (vd->vdev_top == vd && vd->vdev_ashift != 0 &&
1959-
vd->vdev_alloc_bias == VDEV_BIAS_NONE &&
1960-
vd->vdev_islog == 0 && vd->vdev_aux == NULL) {
1961-
if (vd->vdev_ashift > spa->spa_max_ashift)
1962-
spa->spa_max_ashift = vd->vdev_ashift;
1963-
if (vd->vdev_ashift < spa->spa_min_ashift)
1964-
spa->spa_min_ashift = vd->vdev_ashift;
1965-
}
1966-
19671955
/*
19681956
* If this is a leaf vdev, assess whether a resilver is needed.
19691957
* But don't do this if we are doing a reopen for a scrub, since

module/zfs/vdev_removal.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
/*
2323
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24-
* Copyright (c) 2011, 2019 by Delphix. All rights reserved.
24+
* Copyright (c) 2011, 2020 by Delphix. All rights reserved.
2525
* Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
2626
*/
2727

@@ -2030,6 +2030,15 @@ spa_vdev_remove_top_check(vdev_t *vd)
20302030
return (SET_ERROR(EINVAL));
20312031
}
20322032

2033+
/*
2034+
* A removed special/dedup vdev must have same ashift as normal class.
2035+
*/
2036+
ASSERT(!vd->vdev_islog);
2037+
if (vd->vdev_alloc_bias != VDEV_BIAS_NONE &&
2038+
vd->vdev_ashift != spa->spa_max_ashift) {
2039+
return (SET_ERROR(EINVAL));
2040+
}
2041+
20332042
/*
20342043
* All vdevs in normal class must have the same ashift
20352044
* and not be raidz.
@@ -2038,7 +2047,18 @@ spa_vdev_remove_top_check(vdev_t *vd)
20382047
int num_indirect = 0;
20392048
for (uint64_t id = 0; id < rvd->vdev_children; id++) {
20402049
vdev_t *cvd = rvd->vdev_child[id];
2041-
if (cvd->vdev_ashift != 0 && !cvd->vdev_islog)
2050+
2051+
/*
2052+
* A removed special/dedup vdev must have the same ashift
2053+
* across all vdevs in its class.
2054+
*/
2055+
if (vd->vdev_alloc_bias != VDEV_BIAS_NONE &&
2056+
cvd->vdev_alloc_bias == vd->vdev_alloc_bias &&
2057+
cvd->vdev_ashift != vd->vdev_ashift) {
2058+
return (SET_ERROR(EINVAL));
2059+
}
2060+
if (cvd->vdev_ashift != 0 &&
2061+
cvd->vdev_alloc_bias == VDEV_BIAS_NONE)
20422062
ASSERT3U(cvd->vdev_ashift, ==, spa->spa_max_ashift);
20432063
if (cvd->vdev_ops == &vdev_indirect_ops)
20442064
num_indirect++;

0 commit comments

Comments
 (0)