aboutsummaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorTom Caputi <[email protected]>2018-11-07 18:33:17 -0500
committerBrian Behlendorf <[email protected]>2018-11-07 15:33:17 -0800
commit4021ba4cfaa861602ae75d45713224d5a7866004 (patch)
tree31347e819c53a5e42a41a36d132fa4e56a37e4e1 /module
parent95692927f28479c2d3cf0c1e60ad278c8748377c (diff)
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 <[email protected]> Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Tom Caputi <[email protected]> Issue #7732 Closes #8082
Diffstat (limited to 'module')
-rw-r--r--module/zfs/vdev.c9
1 files changed, 8 insertions, 1 deletions
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;
}