From: Tom Caputi Date: Wed, 7 Nov 2018 23:33:17 +0000 (-0500) Subject: Make vdev_set_deferred_resilver() recursive X-Git-Tag: zfs-0.8.0-rc2~17 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4021ba4cfaa861602ae75d45713224d5a7866004;p=zfs 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 Reviewed-by: Brian Behlendorf Signed-off-by: Tom Caputi Issue #7732 Closes #8082 --- diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c index 9a7f5e011..2f28a01c6 100644 --- a/module/zfs/vdev.c +++ b/module/zfs/vdev.c @@ -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; }