diff options
Diffstat (limited to 'module/zfs/zio.c')
-rw-r--r-- | module/zfs/zio.c | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/module/zfs/zio.c b/module/zfs/zio.c index 0912f607f..1915de417 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -32,6 +32,7 @@ #include <sys/txg.h> #include <sys/spa_impl.h> #include <sys/vdev_impl.h> +#include <sys/vdev_trim.h> #include <sys/zio_impl.h> #include <sys/zio_compress.h> #include <sys/zio_checksum.h> @@ -58,7 +59,7 @@ const char *zio_type_name[ZIO_TYPES] = { * Note: Linux kernel thread name length is limited * so these names will differ from upstream open zfs. */ - "z_null", "z_rd", "z_wr", "z_fr", "z_cl", "z_ioctl" + "z_null", "z_rd", "z_wr", "z_fr", "z_cl", "z_ioctl", "z_trim" }; int zio_dva_throttle_enabled = B_TRUE; @@ -761,7 +762,7 @@ zio_create(zio_t *pio, spa_t *spa, uint64_t txg, const blkptr_t *bp, { zio_t *zio; - ASSERT3U(psize, <=, SPA_MAXBLOCKSIZE); + IMPLY(type != ZIO_TYPE_TRIM, psize <= SPA_MAXBLOCKSIZE); ASSERT(P2PHASE(psize, SPA_MINBLOCKSIZE) == 0); ASSERT(P2PHASE(offset, SPA_MINBLOCKSIZE) == 0); @@ -1212,6 +1213,26 @@ zio_ioctl(zio_t *pio, spa_t *spa, vdev_t *vd, int cmd, } zio_t * +zio_trim(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size, + zio_done_func_t *done, void *private, zio_priority_t priority, + enum zio_flag flags, enum trim_flag trim_flags) +{ + zio_t *zio; + + ASSERT0(vd->vdev_children); + ASSERT0(P2PHASE(offset, 1ULL << vd->vdev_ashift)); + ASSERT0(P2PHASE(size, 1ULL << vd->vdev_ashift)); + ASSERT3U(size, !=, 0); + + zio = zio_create(pio, vd->vdev_spa, 0, NULL, NULL, size, size, done, + private, ZIO_TYPE_TRIM, priority, flags | ZIO_FLAG_PHYSICAL, + vd, offset, NULL, ZIO_STAGE_OPEN, ZIO_TRIM_PIPELINE); + zio->io_trim_flags = trim_flags; + + return (zio); +} + +zio_t * zio_read_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size, abd_t *data, int checksum, zio_done_func_t *done, void *private, zio_priority_t priority, enum zio_flag flags, boolean_t labels) @@ -3562,7 +3583,6 @@ zio_alloc_zil(spa_t *spa, objset_t *os, uint64_t txg, blkptr_t *new_bp, * ========================================================================== */ - /* * Issue an I/O to the underlying vdev. Typically the issue pipeline * stops after this stage and will resume upon I/O completion. @@ -3685,8 +3705,8 @@ zio_vdev_io_start(zio_t *zio) return (zio); } - if (vd->vdev_ops->vdev_op_leaf && - (zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE)) { + if (vd->vdev_ops->vdev_op_leaf && (zio->io_type == ZIO_TYPE_READ || + zio->io_type == ZIO_TYPE_WRITE || zio->io_type == ZIO_TYPE_TRIM)) { if (zio->io_type == ZIO_TYPE_READ && vdev_cache_read(zio)) return (zio); @@ -3717,7 +3737,8 @@ zio_vdev_io_done(zio_t *zio) return (NULL); } - ASSERT(zio->io_type == ZIO_TYPE_READ || zio->io_type == ZIO_TYPE_WRITE); + ASSERT(zio->io_type == ZIO_TYPE_READ || + zio->io_type == ZIO_TYPE_WRITE || zio->io_type == ZIO_TYPE_TRIM); if (zio->io_delay) zio->io_delay = gethrtime() - zio->io_delay; @@ -3736,7 +3757,7 @@ zio_vdev_io_done(zio_t *zio) if (zio_injection_enabled && zio->io_error == 0) zio->io_error = zio_handle_label_injection(zio, EIO); - if (zio->io_error) { + if (zio->io_error && zio->io_type != ZIO_TYPE_TRIM) { if (!vdev_accessible(vd, zio)) { zio->io_error = SET_ERROR(ENXIO); } else { @@ -3866,8 +3887,8 @@ zio_vdev_io_assess(zio_t *zio) /* * If a cache flush returns ENOTSUP or ENOTTY, we know that no future - * attempts will ever succeed. In this case we set a persistent bit so - * that we don't bother with it in the future. + * attempts will ever succeed. In this case we set a persistent + * boolean flag so that we don't bother with it in the future. */ if ((zio->io_error == ENOTSUP || zio->io_error == ENOTTY) && zio->io_type == ZIO_TYPE_IOCTL && |