Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Apr 2014 09:00:01 +0000 (UTC)
From:      Steven Hartland <smh@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r265046 - in head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys
Message-ID:  <201404280900.s3S901UT036817@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: smh
Date: Mon Apr 28 09:00:00 2014
New Revision: 265046
URL: http://svnweb.freebsd.org/changeset/base/265046

Log:
  Fix ZIO reordering done by vdev_queue_io causing panics when zio_vdev_io_start
  returns ZIO_PIPELINE_CONTINUE from vdev_op_io_start to zio_execute resulting
  in the wrong ZIO continuing its pipeline.
  
  This is a serious issue which could cause data loss / corruption but appears
  to be limited to error handling such as when vdev_readable(vd) returns false.
  
  MFC after:	2 days

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

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h	Mon Apr 28 07:51:07 2014	(r265045)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h	Mon Apr 28 09:00:00 2014	(r265046)
@@ -349,7 +349,7 @@ typedef struct zio_transform {
 	struct zio_transform	*zt_next;
 } zio_transform_t;
 
-typedef int zio_pipe_stage_t(zio_t *zio);
+typedef int zio_pipe_stage_t(zio_t **ziop);
 
 /*
  * The io_reexecute flags are distinct from io_flags because the child must

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c	Mon Apr 28 07:51:07 2014	(r265045)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c	Mon Apr 28 09:00:00 2014	(r265046)
@@ -1012,8 +1012,9 @@ zio_shrink(zio_t *zio, uint64_t size)
  */
 
 static int
-zio_read_bp_init(zio_t *zio)
+zio_read_bp_init(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	blkptr_t *bp = zio->io_bp;
 
 	if (BP_GET_COMPRESS(bp) != ZIO_COMPRESS_OFF &&
@@ -1038,8 +1039,9 @@ zio_read_bp_init(zio_t *zio)
 }
 
 static int
-zio_write_bp_init(zio_t *zio)
+zio_write_bp_init(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	spa_t *spa = zio->io_spa;
 	zio_prop_t *zp = &zio->io_prop;
 	enum zio_compress compress = zp->zp_compress;
@@ -1189,8 +1191,9 @@ zio_write_bp_init(zio_t *zio)
 }
 
 static int
-zio_free_bp_init(zio_t *zio)
+zio_free_bp_init(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	blkptr_t *bp = zio->io_bp;
 
 	if (zio->io_child_type == ZIO_CHILD_LOGICAL) {
@@ -1273,8 +1276,10 @@ zio_taskq_member(zio_t *zio, zio_taskq_t
 }
 
 static int
-zio_issue_async(zio_t *zio)
+zio_issue_async(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
+
 	zio_taskq_dispatch(zio, ZIO_TASKQ_ISSUE, B_FALSE);
 
 	return (ZIO_PIPELINE_STOP);
@@ -1342,7 +1347,7 @@ zio_execute(zio_t *zio)
 		}
 
 		zio->io_stage = stage;
-		rv = zio_pipeline[highbit64(stage) - 1](zio);
+		rv = zio_pipeline[highbit64(stage) - 1](&zio);
 
 		if (rv == ZIO_PIPELINE_STOP)
 			return;
@@ -1776,8 +1781,9 @@ zio_gang_tree_issue(zio_t *pio, zio_gang
 }
 
 static int
-zio_gang_assemble(zio_t *zio)
+zio_gang_assemble(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	blkptr_t *bp = zio->io_bp;
 
 	ASSERT(BP_IS_GANG(bp) && zio->io_gang_leader == NULL);
@@ -1791,8 +1797,9 @@ zio_gang_assemble(zio_t *zio)
 }
 
 static int
-zio_gang_issue(zio_t *zio)
+zio_gang_issue(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	blkptr_t *bp = zio->io_bp;
 
 	if (zio_wait_for_children(zio, ZIO_CHILD_GANG, ZIO_WAIT_DONE))
@@ -1926,8 +1933,9 @@ zio_write_gang_block(zio_t *pio)
  * writes) and as a result is mutually exclusive with dedup.
  */
 static int
-zio_nop_write(zio_t *zio)
+zio_nop_write(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	blkptr_t *bp = zio->io_bp;
 	blkptr_t *bp_orig = &zio->io_bp_orig;
 	zio_prop_t *zp = &zio->io_prop;
@@ -1998,8 +2006,9 @@ zio_ddt_child_read_done(zio_t *zio)
 }
 
 static int
-zio_ddt_read_start(zio_t *zio)
+zio_ddt_read_start(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	blkptr_t *bp = zio->io_bp;
 
 	ASSERT(BP_GET_DEDUP(bp));
@@ -2041,8 +2050,9 @@ zio_ddt_read_start(zio_t *zio)
 }
 
 static int
-zio_ddt_read_done(zio_t *zio)
+zio_ddt_read_done(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	blkptr_t *bp = zio->io_bp;
 
 	if (zio_wait_for_children(zio, ZIO_CHILD_DDT, ZIO_WAIT_DONE))
@@ -2210,8 +2220,9 @@ zio_ddt_ditto_write_done(zio_t *zio)
 }
 
 static int
-zio_ddt_write(zio_t *zio)
+zio_ddt_write(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	spa_t *spa = zio->io_spa;
 	blkptr_t *bp = zio->io_bp;
 	uint64_t txg = zio->io_txg;
@@ -2322,8 +2333,9 @@ zio_ddt_write(zio_t *zio)
 ddt_entry_t *freedde; /* for debugging */
 
 static int
-zio_ddt_free(zio_t *zio)
+zio_ddt_free(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	spa_t *spa = zio->io_spa;
 	blkptr_t *bp = zio->io_bp;
 	ddt_t *ddt = ddt_select(spa, bp);
@@ -2348,8 +2360,9 @@ zio_ddt_free(zio_t *zio)
  * ==========================================================================
  */
 static int
-zio_dva_allocate(zio_t *zio)
+zio_dva_allocate(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	spa_t *spa = zio->io_spa;
 	metaslab_class_t *mc = spa_normal_class(spa);
 	blkptr_t *bp = zio->io_bp;
@@ -2391,16 +2404,19 @@ zio_dva_allocate(zio_t *zio)
 }
 
 static int
-zio_dva_free(zio_t *zio)
+zio_dva_free(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
+
 	metaslab_free(zio->io_spa, zio->io_bp, zio->io_txg, B_FALSE);
 
 	return (ZIO_PIPELINE_CONTINUE);
 }
 
 static int
-zio_dva_claim(zio_t *zio)
+zio_dva_claim(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	int error;
 
 	error = metaslab_claim(zio->io_spa, zio->io_bp, zio->io_txg);
@@ -2494,8 +2510,9 @@ zio_free_zil(spa_t *spa, uint64_t txg, b
  * ==========================================================================
  */
 static int
-zio_vdev_io_start(zio_t *zio)
+zio_vdev_io_start(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	vdev_t *vd = zio->io_vd;
 	uint64_t align;
 	spa_t *spa = zio->io_spa;
@@ -2589,6 +2606,7 @@ zio_vdev_io_start(zio_t *zio)
 
 		if ((zio = vdev_queue_io(zio)) == NULL)
 			return (ZIO_PIPELINE_STOP);
+		*ziop = zio;
 
 		if (!vdev_accessible(vd, zio)) {
 			zio->io_error = SET_ERROR(ENXIO);
@@ -2612,8 +2630,9 @@ zio_vdev_io_start(zio_t *zio)
 }
 
 static int
-zio_vdev_io_done(zio_t *zio)
+zio_vdev_io_done(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	vdev_t *vd = zio->io_vd;
 	vdev_ops_t *ops = vd ? vd->vdev_ops : &vdev_mirror_ops;
 	boolean_t unexpected_error = B_FALSE;
@@ -2687,8 +2706,9 @@ zio_vsd_default_cksum_report(zio_t *zio,
 }
 
 static int
-zio_vdev_io_assess(zio_t *zio)
+zio_vdev_io_assess(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	vdev_t *vd = zio->io_vd;
 
 	if (zio_wait_for_children(zio, ZIO_CHILD_VDEV, ZIO_WAIT_DONE))
@@ -2801,8 +2821,9 @@ zio_vdev_io_bypass(zio_t *zio)
  * ==========================================================================
  */
 static int
-zio_checksum_generate(zio_t *zio)
+zio_checksum_generate(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	blkptr_t *bp = zio->io_bp;
 	enum zio_checksum checksum;
 
@@ -2832,8 +2853,9 @@ zio_checksum_generate(zio_t *zio)
 }
 
 static int
-zio_checksum_verify(zio_t *zio)
+zio_checksum_verify(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	zio_bad_cksum_t info;
 	blkptr_t *bp = zio->io_bp;
 	int error;
@@ -2904,8 +2926,9 @@ zio_worst_error(int e1, int e2)
  * ==========================================================================
  */
 static int
-zio_ready(zio_t *zio)
+zio_ready(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	blkptr_t *bp = zio->io_bp;
 	zio_t *pio, *pio_next;
 
@@ -2962,8 +2985,9 @@ zio_ready(zio_t *zio)
 }
 
 static int
-zio_done(zio_t *zio)
+zio_done(zio_t **ziop)
 {
+	zio_t *zio = *ziop;
 	spa_t *spa = zio->io_spa;
 	zio_t *lio = zio->io_logical;
 	blkptr_t *bp = zio->io_bp;



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