svn commit: r358605 - stable/12/sys/cddl/contrib/opensolaris/uts/common/fs/zfs

Alexander Motin mav at FreeBSD.org
Wed Mar 4 04:42:57 UTC 2020


Author: mav
Date: Wed Mar  4 04:42:56 2020
New Revision: 358605
URL: https://svnweb.freebsd.org/changeset/base/358605

Log:
  MFC r358342: MFZoL: Fix resilver writes in vdev_indirect_io_start
  
  This patch addresses an issue found in ztest where resilver
  write zios that were passed to an indirect vdev would end up
  being handled as though they were resilver read zios. This
  caused issues where the zio->io_abd would be both read to
  and written from at the same time, causing asserts to fail.
  
  Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
  Reviewed by: Matt Ahrens <matt at delphix.com>
  Reviewed-by: Serapheim Dimitropoulos <serapheim at delphix.com>
  Signed-off-by: Tom Caputi <tcaputi at datto.com>
  Closes #8193
  zfsonlinux/zfs at 5aa95ba0d3502779695341b5f55fa5ba1d3330ff

Modified:
  stable/12/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_indirect.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_indirect.c
==============================================================================
--- stable/12/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_indirect.c	Wed Mar  4 04:42:09 2020	(r358604)
+++ stable/12/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_indirect.c	Wed Mar  4 04:42:56 2020	(r358605)
@@ -1246,6 +1246,8 @@ vdev_indirect_read_all(zio_t *zio)
 {
 	indirect_vsd_t *iv = zio->io_vsd;
 
+	ASSERT3U(zio->io_type, ==, ZIO_TYPE_READ);
+
 	for (indirect_split_t *is = list_head(&iv->iv_splits);
 	    is != NULL; is = list_next(&iv->iv_splits, is)) {
 		for (int i = 0; i < is->is_children; i++) {
@@ -1335,7 +1337,8 @@ vdev_indirect_io_start(zio_t *zio)
 		    vdev_indirect_child_io_done, zio));
 	} else {
 		iv->iv_split_block = B_TRUE;
-		if (zio->io_flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)) {
+		if (zio->io_type == ZIO_TYPE_READ &&
+		    zio->io_flags & (ZIO_FLAG_SCRUB | ZIO_FLAG_RESILVER)) {
 			/*
 			 * Read all copies.  Note that for simplicity,
 			 * we don't bother consulting the DTL in the
@@ -1344,13 +1347,17 @@ vdev_indirect_io_start(zio_t *zio)
 			vdev_indirect_read_all(zio);
 		} else {
 			/*
-			 * Read one copy of each split segment, from the
-			 * top-level vdev.  Since we don't know the
-			 * checksum of each split individually, the child
-			 * zio can't ensure that we get the right data.
-			 * E.g. if it's a mirror, it will just read from a
-			 * random (healthy) leaf vdev.  We have to verify
-			 * the checksum in vdev_indirect_io_done().
+			 * If this is a read zio, we read one copy of each
+			 * split segment, from the top-level vdev.  Since
+			 * we don't know the checksum of each split
+			 * individually, the child zio can't ensure that
+			 * we get the right data. E.g. if it's a mirror,
+			 * it will just read from a random (healthy) leaf
+			 * vdev. We have to verify the checksum in
+			 * vdev_indirect_io_done().
+			 *
+			 * For write zios, the vdev code will ensure we write
+			 * to all children.
 			 */
 			for (indirect_split_t *is = list_head(&iv->iv_splits);
 			    is != NULL; is = list_next(&iv->iv_splits, is)) {


More information about the svn-src-all mailing list