From 20eb30d08e24c2240a5d66e2e62893e784f586af Mon Sep 17 00:00:00 2001 From: Tom Caputi Date: Wed, 7 Nov 2018 18:44:56 -0500 Subject: Fix divide by zero during indirect split damage This patch simply ensures that vdev_indirect_splits_damage() cannot hit a divide by zero exception if a split has no children with valid data. The normal reconstruction code path in vdev_indirect_reconstruct_io_done() already has this check. Reviewed-by: Matthew Ahrens Reviewed-by: Brian Behlendorf Signed-off-by: Tom Caputi Closes #8086 --- module/zfs/vdev_indirect.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'module/zfs/vdev_indirect.c') diff --git a/module/zfs/vdev_indirect.c b/module/zfs/vdev_indirect.c index 7863fe9d0..1bc5676e3 100644 --- a/module/zfs/vdev_indirect.c +++ b/module/zfs/vdev_indirect.c @@ -1587,6 +1587,8 @@ vdev_indirect_splits_enumerate_randomly(indirect_vsd_t *iv, zio_t *zio) static int vdev_indirect_splits_damage(indirect_vsd_t *iv, zio_t *zio) { + int error; + /* Presume all the copies are unique for initial selection. */ for (indirect_split_t *is = list_head(&iv->iv_splits); is != NULL; is = list_next(&iv->iv_splits, is)) { @@ -1599,13 +1601,18 @@ vdev_indirect_splits_damage(indirect_vsd_t *iv, zio_t *zio) list_insert_tail(&is->is_unique_child, ic); } } + + if (list_is_empty(&is->is_unique_child)) { + error = SET_ERROR(EIO); + goto out; + } } /* * Set each is_good_child to a randomly-selected child which * is known to contain validated data. */ - int error = vdev_indirect_splits_enumerate_randomly(iv, zio); + error = vdev_indirect_splits_enumerate_randomly(iv, zio); if (error) goto out; -- cgit v1.2.3