From f7edaefd17f47b76e3ababf834f8a40a90c569a4 Mon Sep 17 00:00:00 2001 From: mav Date: Sun, 20 Mar 2016 20:12:14 +0000 Subject: [PATCH] MFC r274304 (by delphij): MFV r274272 and diff reduction with upstream. Illumos issue: 5244 zio pipeline callers should explicitly invoke next stage git-svn-id: svn://svn.freebsd.org/base/stable/10@297078 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- .../opensolaris/lib/libzpool/common/taskq.c | 4 +++ .../uts/common/fs/zfs/sys/vdev_impl.h | 2 +- .../opensolaris/uts/common/fs/zfs/sys/zio.h | 3 --- .../opensolaris/uts/common/fs/zfs/vdev_disk.c | 14 +++++----- .../opensolaris/uts/common/fs/zfs/vdev_file.c | 15 ++++++----- .../opensolaris/uts/common/fs/zfs/vdev_geom.c | 16 ++++++------ .../uts/common/fs/zfs/vdev_mirror.c | 11 ++++---- .../uts/common/fs/zfs/vdev_missing.c | 7 +++-- .../uts/common/fs/zfs/vdev_raidz.c | 15 +++++------ .../opensolaris/uts/common/fs/zfs/zio.c | 26 ++++++++++++++----- 10 files changed, 63 insertions(+), 50 deletions(-) diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/taskq.c b/cddl/contrib/opensolaris/lib/libzpool/common/taskq.c index 785f10678..26d9f364b 100644 --- a/cddl/contrib/opensolaris/lib/libzpool/common/taskq.c +++ b/cddl/contrib/opensolaris/lib/libzpool/common/taskq.c @@ -25,6 +25,7 @@ /* * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright 2012 Garrett D'Amore . All rights reserved. + * Copyright (c) 2014 by Delphix. All rights reserved. */ #include @@ -33,8 +34,10 @@ int taskq_now; taskq_t *system_taskq; #define TASKQ_ACTIVE 0x00010000 +#define TASKQ_NAMELEN 31 struct taskq { + char tq_name[TASKQ_NAMELEN + 1]; kmutex_t tq_lock; krwlock_t tq_threadlock; kcondvar_t tq_dispatch_cv; @@ -247,6 +250,7 @@ taskq_create(const char *name, int nthreads, pri_t pri, cv_init(&tq->tq_dispatch_cv, NULL, CV_DEFAULT, NULL); cv_init(&tq->tq_wait_cv, NULL, CV_DEFAULT, NULL); cv_init(&tq->tq_maxalloc_cv, NULL, CV_DEFAULT, NULL); + (void) strncpy(tq->tq_name, name, TASKQ_NAMELEN + 1); tq->tq_flags = flags | TASKQ_ACTIVE; tq->tq_active = nthreads; tq->tq_nthreads = nthreads; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h index a31d04ceb..77e291be3 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h @@ -60,7 +60,7 @@ typedef int vdev_open_func_t(vdev_t *vd, uint64_t *size, uint64_t *max_size, uint64_t *logical_ashift, uint64_t *physical_ashift); typedef void vdev_close_func_t(vdev_t *vd); typedef uint64_t vdev_asize_func_t(vdev_t *vd, uint64_t psize); -typedef int vdev_io_start_func_t(zio_t *zio); +typedef void vdev_io_start_func_t(zio_t *zio); typedef void vdev_io_done_func_t(zio_t *zio); typedef void vdev_state_change_func_t(vdev_t *vd, int, int); typedef void vdev_hold_func_t(vdev_t *vd); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h index 16d9ad25b..eac4b905c 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h @@ -150,9 +150,6 @@ enum zio_compress { #define ZIO_FAILURE_MODE_CONTINUE 1 #define ZIO_FAILURE_MODE_PANIC 2 -#define ZIO_PIPELINE_CONTINUE 0x100 -#define ZIO_PIPELINE_STOP 0x101 - enum zio_flag { /* * Flags inherited by gang, ddt, and vdev children, diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c index eaa9dfcfb..c397891d4 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c @@ -715,7 +715,7 @@ vdev_disk_ioctl_done(void *zio_arg, int error) zio_interrupt(zio); } -static int +static void vdev_disk_io_start(zio_t *zio) { vdev_t *vd = zio->io_vd; @@ -732,7 +732,7 @@ vdev_disk_io_start(zio_t *zio) if (dvd == NULL || (dvd->vd_ldi_offline && dvd->vd_lh == NULL)) { zio->io_error = SET_ERROR(ENXIO); zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + return; } if (zio->io_type == ZIO_TYPE_IOCTL) { @@ -740,7 +740,7 @@ vdev_disk_io_start(zio_t *zio) if (!vdev_readable(vd)) { zio->io_error = SET_ERROR(ENXIO); zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + return; } switch (zio->io_cmd) { @@ -771,7 +771,7 @@ vdev_disk_io_start(zio_t *zio) * and will call vdev_disk_ioctl_done() * upon completion. */ - return (ZIO_PIPELINE_STOP); + return; } if (error == ENOTSUP || error == ENOTTY) { @@ -792,8 +792,8 @@ vdev_disk_io_start(zio_t *zio) zio->io_error = SET_ERROR(ENOTSUP); } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE); @@ -816,8 +816,6 @@ vdev_disk_io_start(zio_t *zio) /* ldi_strategy() will return non-zero only on programming errors */ VERIFY(ldi_strategy(dvd->vd_lh, bp) == 0); - - return (ZIO_PIPELINE_STOP); } static void diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c index ad21d6e17..01ef7563e 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2011, 2014 by Delphix. All rights reserved. */ #include @@ -156,7 +156,7 @@ vdev_file_close(vdev_t *vd) vd->vdev_tsd = NULL; } -static int +static void vdev_file_io_start(zio_t *zio) { vdev_t *vd = zio->io_vd; @@ -167,7 +167,7 @@ vdev_file_io_start(zio_t *zio) if (!vdev_readable(vd)) { zio->io_error = SET_ERROR(ENXIO); zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + return; } vf = vd->vdev_tsd; @@ -183,8 +183,8 @@ vdev_file_io_start(zio_t *zio) zio->io_error = SET_ERROR(ENOTSUP); } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE); @@ -198,7 +198,10 @@ vdev_file_io_start(zio_t *zio) zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); +#ifdef illumos + VERIFY3U(taskq_dispatch(system_taskq, vdev_file_io_strategy, bp, + TQ_SLEEP), !=, 0); +#endif } /* ARGSUSED */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c index 763ea1a4a..323a65784 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c @@ -814,7 +814,7 @@ vdev_geom_io_intr(struct bio *bp) zio_interrupt(zio); } -static int +static void vdev_geom_io_start(zio_t *zio) { vdev_t *vd; @@ -829,6 +829,8 @@ vdev_geom_io_start(zio_t *zio) /* XXPOLICY */ if (!vdev_readable(vd)) { zio->io_error = SET_ERROR(ENXIO); + zio_interrupt(zio); + return; } else { switch (zio->io_cmd) { case DKIOCFLUSHWRITECACHE: @@ -844,16 +846,16 @@ vdev_geom_io_start(zio_t *zio) } } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; case ZIO_TYPE_FREE: if (vd->vdev_notrim) { zio->io_error = SET_ERROR(ENOTSUP); } else if (!vdev_geom_bio_delete_disable) { goto sendreq; } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } sendreq: ASSERT(zio->io_type == ZIO_TYPE_READ || @@ -865,7 +867,7 @@ vdev_geom_io_start(zio_t *zio) if (cp == NULL) { zio->io_error = SET_ERROR(ENXIO); zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + return; } bp = g_alloc_bio(); bp->bio_caller1 = zio; @@ -894,8 +896,6 @@ vdev_geom_io_start(zio_t *zio) bp->bio_done = vdev_geom_io_intr; g_io_request(bp, cp); - - return (ZIO_PIPELINE_STOP); } static void 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 9d22d1e0c..65acd47b1 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 @@ -24,7 +24,7 @@ */ /* - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2012, 2014 by Delphix. All rights reserved. */ #include @@ -431,7 +431,7 @@ vdev_mirror_child_select(zio_t *zio) return (-1); } -static int +static void vdev_mirror_io_start(zio_t *zio) { mirror_map_t *mm; @@ -457,8 +457,8 @@ vdev_mirror_io_start(zio_t *zio) zio->io_type, zio->io_priority, 0, vdev_mirror_scrub_done, mc)); } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } /* * For normal reads just pick one child. @@ -485,8 +485,7 @@ vdev_mirror_io_start(zio_t *zio) c++; } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); } static int diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c index fec0037b2..24a44a697 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c @@ -24,7 +24,7 @@ */ /* - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2012, 2014 by Delphix. All rights reserved. */ /* @@ -67,12 +67,11 @@ vdev_missing_close(vdev_t *vd) } /* ARGSUSED */ -static int +static void vdev_missing_io_start(zio_t *zio) { zio->io_error = SET_ERROR(ENOTSUP); - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); } /* ARGSUSED */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c index 33bedc159..6b538cf56 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013 by Delphix. All rights reserved. + * Copyright (c) 2012, 2014 by Delphix. All rights reserved. * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ @@ -1726,7 +1726,7 @@ vdev_raidz_child_done(zio_t *zio) * vdevs have had errors, then create zio read operations to the parity * columns' VDevs as well. */ -static int +static void vdev_raidz_io_start(zio_t *zio) { vdev_t *vd = zio->io_vd; @@ -1756,8 +1756,8 @@ vdev_raidz_io_start(zio_t *zio) vdev_raidz_child_done, rc)); } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } if (zio->io_type == ZIO_TYPE_WRITE) { @@ -1789,8 +1789,8 @@ vdev_raidz_io_start(zio_t *zio) ZIO_FLAG_NODATA | ZIO_FLAG_OPTIONAL, NULL, NULL)); } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); + return; } ASSERT(zio->io_type == ZIO_TYPE_READ); @@ -1830,8 +1830,7 @@ vdev_raidz_io_start(zio_t *zio) } } - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + zio_execute(zio); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c index cce7fd1d1..c98ec0ed9 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c @@ -93,6 +93,9 @@ kmem_cache_t *zio_data_buf_cache[SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT]; extern vmem_t *zio_alloc_arena; #endif +#define ZIO_PIPELINE_CONTINUE 0x100 +#define ZIO_PIPELINE_STOP 0x101 + #define BP_SPANB(indblkshift, level) \ (((uint64_t)1) << ((level) * ((indblkshift) - SPA_BLKPTRSHIFT))) #define COMPARE_META_LEVEL 0x80000000ul @@ -2662,6 +2665,18 @@ zio_free_zil(spa_t *spa, uint64_t txg, blkptr_t *bp) * Read, write and delete to physical devices * ========================================================================== */ + + +/* + * Issue an I/O to the underlying vdev. Typically the issue pipeline + * stops after this stage and will resume upon I/O completion. + * However, there are instances where the vdev layer may need to + * continue the pipeline when an I/O was not issued. Since the I/O + * that was sent to the vdev layer might be different than the one + * currently active in the pipeline (see vdev_queue_io()), we explicitly + * force the underlying vdev layers to call either zio_execute() or + * zio_interrupt() to ensure that the pipeline continues with the correct I/O. + */ static int zio_vdev_io_start(zio_t *zio) { @@ -2680,7 +2695,8 @@ zio_vdev_io_start(zio_t *zio) /* * The mirror_ops handle multiple DVAs in a single BP. */ - return (vdev_mirror_ops.vdev_op_io_start(zio)); + vdev_mirror_ops.vdev_op_io_start(zio); + return (ZIO_PIPELINE_STOP); } if (vd->vdev_ops->vdev_op_leaf && zio->io_type == ZIO_TYPE_FREE && @@ -2694,7 +2710,7 @@ zio_vdev_io_start(zio_t *zio) * can quickly react to certain workloads. In particular, we care * about non-scrubbing, top-level reads and writes with the following * characteristics: - * - synchronous writes of user data to non-slog devices + * - synchronous writes of user data to non-slog devices * - any reads of user data * When these conditions are met, adjust the timestamp of spa_last_io * which allows the scan thread to adjust its workload accordingly. @@ -2798,10 +2814,8 @@ zio_vdev_io_start(zio_t *zio) return (ZIO_PIPELINE_STOP); } - ret = vd->vdev_ops->vdev_op_io_start(zio); - ASSERT(ret == ZIO_PIPELINE_STOP); - - return (ret); + vd->vdev_ops->vdev_op_io_start(zio); + return (ZIO_PIPELINE_STOP); } static int -- 2.45.0