Make vdev_set_deferred_resilver() recursive

vdev_clear() can call vdev_set_deferred_resilver() with a
non-leaf vdev to setup a deferred resilver. However, this
function is currently written to only handle leaf vdevs.
This bug was introduced with deferred resilvers in 80a91e74.
This patch makes this function recursive so that it can find
appropriate vdevs to resilver and set vdev_resilver_deferred
on them.

Reviewed-by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Tom Caputi <tcaputi@datto.com>
Issue #7732
Closes #8082
This commit is contained in:
Tom Caputi 2018-11-07 18:33:17 -05:00 committed by Brian Behlendorf
parent 95692927f2
commit 4021ba4cfa

View File

@ -4598,7 +4598,14 @@ vdev_deadman(vdev_t *vd, char *tag)
void
vdev_set_deferred_resilver(spa_t *spa, vdev_t *vd)
{
ASSERT(vd->vdev_ops->vdev_op_leaf);
for (uint64_t i = 0; i < vd->vdev_children; i++)
vdev_set_deferred_resilver(spa, vd->vdev_child[i]);
if (!vd->vdev_ops->vdev_op_leaf || !vdev_writeable(vd) ||
range_tree_is_empty(vd->vdev_dtl[DTL_MISSING])) {
return;
}
vd->vdev_resilver_deferred = B_TRUE;
spa->spa_resilver_deferred = B_TRUE;
}