Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Jan 2014 13:24:10 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r260713 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <201401161324.s0GDOADB008512@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Thu Jan 16 13:24:10 2014
New Revision: 260713
URL: http://svnweb.freebsd.org/changeset/base/260713

Log:
  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

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c	Thu Jan 16 13:21:32 2014	(r260712)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c	Thu Jan 16 13:24:10 2014	(r260713)
@@ -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(zi
 
 	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));
 	}
 
 	/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401161324.s0GDOADB008512>