summaryrefslogtreecommitdiffstats
path: root/sys/cddl
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2014-01-16 13:24:10 +0000
committeravg <avg@FreeBSD.org>2014-01-16 13:24:10 +0000
commite186f564bc946f82c76e0b34c2f0370ed9aea022 (patch)
tree3debc97b6d1f4e0cf82f35235031f54165985478 /sys/cddl
parentd1329f5a229d69a6b70fe9ba812bf09ae0443e3a (diff)
downloadFreeBSD-src-e186f564bc946f82c76e0b34c2f0370ed9aea022.zip
FreeBSD-src-e186f564bc946f82c76e0b34c2f0370ed9aea022.tar.gz
fix a bug in ZFS mirror code for handling multiple DVAa
The bug was introduced in r256956 "Improve ZFS N-way mirror read performance". The code in vdev_mirror_dva_select erroneously considers already tried DVAs for the next attempt. Thus, it is possible that a failing DVA would be retried forever. As a secondary effect, if the attempts fail with checksum error, then checksum error reports are accumulated until the original request ultimately fails or succeeds. But because retrying is going on indefinitely the cheksum reports accumulation will effectively be a memory leak. Reviewed by: gibbs MFC after: 13 days Sponsored by: HybridCluster
Diffstat (limited to 'sys/cddl')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c
index 1ffd1de..0b8d449 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c
@@ -313,13 +313,16 @@ vdev_mirror_scrub_done(zio_t *zio)
* single-copy data.
*/
static int
-vdev_mirror_dva_select(zio_t *zio, int preferred)
+vdev_mirror_dva_select(zio_t *zio, int p)
{
dva_t *dva = zio->io_bp->blk_dva;
mirror_map_t *mm = zio->io_vsd;
+ int preferred;
int c;
- for (c = preferred - 1; c >= 0; c--) {
+ preferred = mm->mm_preferred[p];
+ for (p-- ; p >= 0; p--) {
+ c = mm->mm_preferred[p];
if (DVA_GET_VDEV(&dva[c]) == DVA_GET_VDEV(&dva[preferred]))
preferred = c;
}
@@ -334,7 +337,7 @@ vdev_mirror_preferred_child_randomize(zio_t *zio)
if (mm->mm_root) {
p = spa_get_random(mm->mm_preferred_cnt);
- return (vdev_mirror_dva_select(zio, mm->mm_preferred[p]));
+ return (vdev_mirror_dva_select(zio, p));
}
/*
OpenPOWER on IntegriCloud