Fix other nonrot bugs

There are still a variety of bugs involving the vdev_nonrot property
that will cause problems if you try to run the test suite with
segment-based weighting disabled, and with other things in the weighting
code. Parents' nonrot property need to be updated when children are
added. When vdevs are expanded and more metaslabs are added, the weights
have to be recalculated (since the number of metaslabs is an input to
the lba bias function). When opening, faulted or unopenable children
should not be considered for whether a vdev is nonrot or not (since the
nonrot property is determined during a successful open, this can cause
false negatives). And draid spares need to have the nonrot property set
correctly.

Sponsored-by: Eshtek, creators of HexOS
Sponsored-by: Klara, Inc.
Reviewed-by: Allan Jude <allan@klarasystems.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Reviewed-by: Rob Norris <robn@despairlabs.com>
Signed-off-by: Paul Dagnelie <paul.dagnelie@klarasystems.com>
Closes #17469
This commit is contained in:
Paul Dagnelie 2025-06-19 06:25:58 -07:00 committed by GitHub
parent 585dbbf13b
commit 717213d431
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 19 additions and 0 deletions

View File

@ -553,6 +553,7 @@ vdev_add_child(vdev_t *pvd, vdev_t *cvd)
pvd->vdev_child = newchild; pvd->vdev_child = newchild;
pvd->vdev_child[id] = cvd; pvd->vdev_child[id] = cvd;
pvd->vdev_nonrot &= cvd->vdev_nonrot;
cvd->vdev_top = (pvd->vdev_top ? pvd->vdev_top: cvd); cvd->vdev_top = (pvd->vdev_top ? pvd->vdev_top: cvd);
ASSERT(cvd->vdev_top->vdev_parent->vdev_parent == NULL); ASSERT(cvd->vdev_top->vdev_parent->vdev_parent == NULL);
@ -1374,6 +1375,7 @@ vdev_add_parent(vdev_t *cvd, vdev_ops_t *ops)
mvd->vdev_physical_ashift = cvd->vdev_physical_ashift; mvd->vdev_physical_ashift = cvd->vdev_physical_ashift;
mvd->vdev_state = cvd->vdev_state; mvd->vdev_state = cvd->vdev_state;
mvd->vdev_crtxg = cvd->vdev_crtxg; mvd->vdev_crtxg = cvd->vdev_crtxg;
mvd->vdev_nonrot = cvd->vdev_nonrot;
vdev_remove_child(pvd, cvd); vdev_remove_child(pvd, cvd);
vdev_add_child(pvd, mvd); vdev_add_child(pvd, mvd);
@ -1579,6 +1581,18 @@ vdev_metaslab_init(vdev_t *vd, uint64_t txg)
vd->vdev_ms = mspp; vd->vdev_ms = mspp;
vd->vdev_ms_count = newc; vd->vdev_ms_count = newc;
/*
* Weighting algorithms can depend on the number of metaslabs in the
* vdev. In order to ensure that all weights are correct at all times,
* we need to recalculate here.
*/
for (uint64_t m = 0; m < oldc; m++) {
metaslab_t *msp = vd->vdev_ms[m];
mutex_enter(&msp->ms_lock);
metaslab_recalculate_weight_and_sort(msp);
mutex_exit(&msp->ms_lock);
}
for (uint64_t m = oldc; m < newc; m++) { for (uint64_t m = oldc; m < newc; m++) {
uint64_t object = 0; uint64_t object = 0;
/* /*
@ -1960,6 +1974,10 @@ vdev_open_children_impl(vdev_t *vd, vdev_open_children_func_t *open_func)
taskq_wait(tq); taskq_wait(tq);
for (int c = 0; c < children; c++) { for (int c = 0; c < children; c++) {
vdev_t *cvd = vd->vdev_child[c]; vdev_t *cvd = vd->vdev_child[c];
if (open_func(cvd) == B_FALSE ||
cvd->vdev_state <= VDEV_STATE_FAULTED)
continue;
vd->vdev_nonrot &= cvd->vdev_nonrot; vd->vdev_nonrot &= cvd->vdev_nonrot;
} }

View File

@ -2484,6 +2484,7 @@ vdev_draid_spare_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
*max_psize = max_asize + VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE; *max_psize = max_asize + VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE;
vds->vds_draid_vdev = tvd; vds->vds_draid_vdev = tvd;
vd->vdev_nonrot = tvd->vdev_nonrot;
return (0); return (0);
} }