mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
Fix metaslab count assertion in metaslab_group_alloc() for small vdevs
When creating a pool on a small vdev (< 1GB) with a low zfs_vdev_min_ms_count value (e.g., 2), vdev_metaslab_set_size() could compute a metaslab shift that results in fewer metaslabs than zfs_vdev_min_ms_count, triggering an assertion failure in metaslab_group_alloc(): ASSERT3U(mg->mg_vd->vdev_ms_count, >=, 2) failed (1 >= 2) The root cause is that highbit64(asize / zfs_vdev_min_ms_count) returns last set bit, which can yield a metaslab size larger than asize / zfs_vdev_min_ms_count. For example, with a 500MB vdev and zfs_vdev_min_ms_count=2: - asize / 2 = 250MB - highbit64(250MB) = 28, giving 256MB metaslabs - 500MB / 256MB = 1 metaslab (violates minimum of 2) Fix by subtracting 1 from highbit64() result to ensure the metaslab size is at most asize / zfs_vdev_min_ms_count, guaranteeing at least zfs_vdev_min_ms_count metaslabs are created. Test fixes: trim/autotrim_config.ksh: Increase post-trim thresholds from 30% to 40% (45% for draid). With the metaslab fix, smaller vdevs now create more metaslabs as intended, which increases spacemap metadata overhead. Adjust the post-trim size threshold to accommodate this expected overhead. replacement/replace_resilver_sit_out.ksh: Increase test vdev size from 150MB to 256MB. With the metaslab fix, 150MB vdevs create 18 metaslabs (vs 9 before), changing read distribution patterns and preventing the sit_out outlier detection from triggering reliably. Larger vdevs provide more consistent read patterns for the latency-based sit_out mechanism. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Alexander Motin <[email protected]> Signed-off-by: Jitendra Patidar <[email protected]> Closes #19031
This commit is contained in:
1 parent
02b5baf13c
commit
994fb17039
3 files changed
+9
-4
No files matched your search
+5
-1
@@ -3102,7 +3102,11 @@ vdev_metaslab_set_size(vdev_t *vd)
|
||||
*/
|
||||
|
||||
if (ms_count < zfs_vdev_min_ms_count)
|
||||
ms_shift = highbit64(asize / zfs_vdev_min_ms_count);
|
||||
/*
|
||||
* Subtract 1 from highbit64() to ensure ms_shift yields
|
||||
* at least zfs_vdev_min_ms_count metaslabs.
|
||||
*/
|
||||
ms_shift = highbit64(asize / zfs_vdev_min_ms_count) - 1;
|
||||
else if (ms_count > zfs_vdev_default_ms_count)
|
||||
ms_shift = highbit64(asize / zfs_vdev_default_ms_count);
|
||||
else
|
||||
|
||||
@@ -130,7 +130,7 @@ function replace_test
|
||||
verify_pool $TESTPOOL1
|
||||
}
|
||||
|
||||
DEVSIZE="150M"
|
||||
DEVSIZE="256M"
|
||||
specials_list=""
|
||||
i=0
|
||||
while [[ $i != 10 ]]; do
|
||||
|
||||
@@ -71,7 +71,7 @@ typeset vdev_min_ms_count=$(get_tunable VDEV_MIN_MS_COUNT)
|
||||
log_must set_tunable64 VDEV_MIN_MS_COUNT 32
|
||||
|
||||
typeset VDEV_MAX_MB=$(( floor(4 * MINVDEVSIZE * 0.75 / 1024 / 1024) ))
|
||||
typeset VDEV_MIN_MB=$(( floor(4 * MINVDEVSIZE * 0.30 / 1024 / 1024) ))
|
||||
typeset VDEV_MIN_MB=$(( floor(4 * MINVDEVSIZE * 0.40 / 1024 / 1024) ))
|
||||
|
||||
for type in "" "mirror" "raidz2" "draid"; do
|
||||
|
||||
@@ -85,8 +85,9 @@ for type in "" "mirror" "raidz2" "draid"; do
|
||||
VDEVS="$TRIM_VDEV1 $TRIM_VDEV2 $TRIM_VDEV3 $TRIM_VDEV4"
|
||||
|
||||
# The per-vdev utilization is lower due to the capacity
|
||||
# resilverd for the distributed spare.
|
||||
# reserved for the distributed spare.
|
||||
VDEV_MAX_MB=$(( floor(4 * MINVDEVSIZE * 0.50 / 1024 / 1024) ))
|
||||
VDEV_MIN_MB=$(( floor(4 * MINVDEVSIZE * 0.45 / 1024 / 1024) ))
|
||||
fi
|
||||
|
||||
log_must truncate -s $((4 * MINVDEVSIZE)) $VDEVS
|
||||
|
||||
Reference in new issue
Block a user