diff options
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c | 150 |
1 files changed, 95 insertions, 55 deletions
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 ea81b43..01946fb 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c @@ -788,6 +788,8 @@ zio_free_sync(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp, else if (BP_IS_GANG(bp) || BP_GET_DEDUP(bp)) stage |= ZIO_STAGE_ISSUE_ASYNC; + flags |= ZIO_FLAG_DONT_QUEUE; + zio = zio_create(pio, spa, txg, bp, NULL, size, NULL, NULL, ZIO_TYPE_FREE, ZIO_PRIORITY_NOW, flags, NULL, 0, NULL, ZIO_STAGE_OPEN, stage); @@ -827,14 +829,14 @@ zio_claim(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp, zio_t * zio_ioctl(zio_t *pio, spa_t *spa, vdev_t *vd, int cmd, uint64_t offset, uint64_t size, zio_done_func_t *done, void *private, - enum zio_flag flags) + zio_priority_t priority, enum zio_flag flags) { zio_t *zio; int c; if (vd->vdev_children == 0) { zio = zio_create(pio, spa, 0, NULL, NULL, size, done, private, - ZIO_TYPE_IOCTL, ZIO_PRIORITY_NOW, flags, vd, offset, NULL, + ZIO_TYPE_IOCTL, priority, flags, vd, offset, NULL, ZIO_STAGE_OPEN, ZIO_IOCTL_PIPELINE); zio->io_cmd = cmd; @@ -843,7 +845,7 @@ zio_ioctl(zio_t *pio, spa_t *spa, vdev_t *vd, int cmd, uint64_t offset, for (c = 0; c < vd->vdev_children; c++) zio_nowait(zio_ioctl(zio, spa, vd->vdev_child[c], cmd, - offset, size, done, private, flags)); + offset, size, done, private, priority, flags)); } return (zio); @@ -928,6 +930,10 @@ zio_vdev_child_io(zio_t *pio, blkptr_t *bp, vdev_t *vd, uint64_t offset, pio->io_pipeline &= ~ZIO_STAGE_CHECKSUM_VERIFY; } + /* Not all IO types require vdev io done stage e.g. free */ + if (!(pio->io_pipeline & ZIO_STAGE_VDEV_IO_DONE)) + pipeline &= ~ZIO_STAGE_VDEV_IO_DONE; + if (vd->vdev_children == 0) offset += VDEV_LABEL_START_SIZE; @@ -973,7 +979,7 @@ void zio_flush(zio_t *zio, vdev_t *vd) { zio_nowait(zio_ioctl(zio, zio->io_spa, vd, DKIOCFLUSHWRITECACHE, 0, 0, - NULL, NULL, + NULL, NULL, ZIO_PRIORITY_NOW, ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE | ZIO_FLAG_DONT_RETRY)); } @@ -983,9 +989,10 @@ zio_trim(zio_t *zio, spa_t *spa, vdev_t *vd, uint64_t offset, uint64_t size) ASSERT(vd->vdev_ops->vdev_op_leaf); - return zio_ioctl(zio, spa, vd, DKIOCTRIM, offset, size, - NULL, NULL, - ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE | ZIO_FLAG_DONT_RETRY); + return (zio_create(zio, spa, 0, NULL, NULL, size, NULL, NULL, + ZIO_TYPE_FREE, ZIO_PRIORITY_TRIM, ZIO_FLAG_DONT_AGGREGATE | + ZIO_FLAG_CANFAIL | ZIO_FLAG_DONT_PROPAGATE | ZIO_FLAG_DONT_RETRY, + vd, offset, NULL, ZIO_STAGE_OPEN, ZIO_FREE_PHYS_PIPELINE)); } void @@ -1012,8 +1019,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 +1046,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 +1198,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 +1283,10 @@ zio_taskq_member(zio_t *zio, zio_taskq_type_t q) } 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 +1354,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 +1788,9 @@ zio_gang_tree_issue(zio_t *pio, zio_gang_node_t *gn, blkptr_t *bp, void *data) } 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 +1804,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 +1940,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 +2013,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 +2057,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 +2227,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 +2340,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 +2367,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 +2411,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 +2517,9 @@ zio_free_zil(spa_t *spa, uint64_t txg, blkptr_t *bp) * ========================================================================== */ 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; @@ -2513,7 +2537,8 @@ zio_vdev_io_start(zio_t *zio) return (vdev_mirror_ops.vdev_op_io_start(zio)); } - if (vd->vdev_ops->vdev_op_leaf && zio->io_type == ZIO_TYPE_FREE) { + if (vd->vdev_ops->vdev_op_leaf && zio->io_type == ZIO_TYPE_FREE && + zio->io_priority == ZIO_PRIORITY_NOW) { trim_map_free(vd, zio->io_offset, zio->io_size, zio->io_txg); return (ZIO_PIPELINE_CONTINUE); } @@ -2581,30 +2606,33 @@ zio_vdev_io_start(zio_t *zio) return (ZIO_PIPELINE_CONTINUE); } - if (vd->vdev_ops->vdev_op_leaf && - (zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE)) { - - if (zio->io_type == ZIO_TYPE_READ && vdev_cache_read(zio)) - return (ZIO_PIPELINE_CONTINUE); + if (vd->vdev_ops->vdev_op_leaf) { + switch (zio->io_type) { + case ZIO_TYPE_READ: + if (vdev_cache_read(zio)) + return (ZIO_PIPELINE_CONTINUE); + /* FALLTHROUGH */ + case ZIO_TYPE_WRITE: + case ZIO_TYPE_FREE: + if ((zio = vdev_queue_io(zio)) == NULL) + return (ZIO_PIPELINE_STOP); + *ziop = zio; - if ((zio = vdev_queue_io(zio)) == NULL) - return (ZIO_PIPELINE_STOP); - - if (!vdev_accessible(vd, zio)) { - zio->io_error = SET_ERROR(ENXIO); - zio_interrupt(zio); - return (ZIO_PIPELINE_STOP); + if (!vdev_accessible(vd, zio)) { + zio->io_error = SET_ERROR(ENXIO); + zio_interrupt(zio); + return (ZIO_PIPELINE_STOP); + } + break; } - } - - /* - * Note that we ignore repair writes for TRIM because they can conflict - * with normal writes. This isn't an issue because, by definition, we - * only repair blocks that aren't freed. - */ - if (vd->vdev_ops->vdev_op_leaf && zio->io_type == ZIO_TYPE_WRITE && - !(zio->io_flags & ZIO_FLAG_IO_REPAIR)) { - if (!trim_map_write_start(zio)) + /* + * Note that we ignore repair writes for TRIM because they can + * conflict with normal writes. This isn't an issue because, by + * definition, we only repair blocks that aren't freed. + */ + if (zio->io_type == ZIO_TYPE_WRITE && + !(zio->io_flags & ZIO_FLAG_IO_REPAIR) && + !trim_map_write_start(zio)) return (ZIO_PIPELINE_STOP); } @@ -2612,8 +2640,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; @@ -2625,7 +2654,8 @@ zio_vdev_io_done(zio_t *zio) zio->io_type == ZIO_TYPE_WRITE || zio->io_type == ZIO_TYPE_FREE); if (vd != NULL && vd->vdev_ops->vdev_op_leaf && - (zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE)) { + (zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE || + zio->io_type == ZIO_TYPE_FREE)) { if (zio->io_type == ZIO_TYPE_WRITE && !(zio->io_flags & ZIO_FLAG_IO_REPAIR)) @@ -2644,7 +2674,10 @@ zio_vdev_io_done(zio_t *zio) zio->io_error = zio_handle_label_injection(zio, EIO); if (zio->io_error) { - if (!vdev_accessible(vd, zio)) { + if (zio->io_error == ENOTSUP && + zio->io_type == ZIO_TYPE_FREE) { + /* Not all devices support TRIM. */ + } else if (!vdev_accessible(vd, zio)) { zio->io_error = SET_ERROR(ENXIO); } else { unexpected_error = B_TRUE; @@ -2687,8 +2720,9 @@ zio_vsd_default_cksum_report(zio_t *zio, zio_cksum_report_t *zcr, void *ignored) } 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)) @@ -2705,7 +2739,8 @@ zio_vdev_io_assess(zio_t *zio) if (zio_injection_enabled && zio->io_error == 0) zio->io_error = zio_handle_fault_injection(zio, EIO); - if (zio->io_type == ZIO_TYPE_IOCTL && zio->io_cmd == DKIOCTRIM) + if (zio->io_type == ZIO_TYPE_FREE && + zio->io_priority != ZIO_PRIORITY_NOW) { switch (zio->io_error) { case 0: ZIO_TRIM_STAT_INCR(bytes, zio->io_size); @@ -2718,6 +2753,7 @@ zio_vdev_io_assess(zio_t *zio) ZIO_TRIM_STAT_BUMP(failed); break; } + } /* * If the I/O failed, determine whether we should attempt to retry it. @@ -2801,8 +2837,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 +2869,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 +2942,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 +3001,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; |