From ddc6d7e1606cec39baddb1206aebc272a0b2c8d4 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 15 Feb 2020 02:54:10 +0000 Subject: [PATCH] Experimental support for TRIM in ZFS. WARNING: THIS MAY OBLITERATE YOUR DATA IF I MADE A MISTAKE. AND NOT THE DATA YOU MEANT TO OBLITERATE BY USING TRIM. --- .../osnet/dist/uts/common/fs/zfs/vdev_disk.c | 92 ++++++++++++------- .../osnet/dist/uts/common/fs/zfs/zfs_ioctl.c | 3 - 2 files changed, 60 insertions(+), 35 deletions(-) diff --git a/external/cddl/osnet/dist/uts/common/fs/zfs/vdev_disk.c b/external/cddl/osnet/dist/uts/common/fs/zfs/vdev_disk.c index 000174281f46..58511e8dff92 100644 --- a/external/cddl/osnet/dist/uts/common/fs/zfs/vdev_disk.c +++ b/external/cddl/osnet/dist/uts/common/fs/zfs/vdev_disk.c @@ -119,23 +119,43 @@ vdev_disk_rele(vdev_t *vd) } static void -vdev_disk_flush(struct work *work, void *cookie) +vdev_async_cmd(struct work *work, void *cookie) { vdev_disk_t *dvd; int error, cmd; buf_t *bp; + zio_t *zio; vnode_t *vp; - bp = (struct buf *)work; + bp = container_of(work, struct buf, b_work); + zio = bp->b_private; vp = bp->b_vp; dvd = cookie; KASSERT(vp == dvd->vd_vp); - cmd = 1; - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - error = VOP_IOCTL(vp, DIOCCACHESYNC, &cmd, FREAD|FWRITE, kcred); - VOP_UNLOCK(vp, 0); + switch (zio->io_type) { + case ZIO_TYPE_IOCTL: + switch (zio->io_cmd) { + case DKIOCFLUSHWRITECACHE: + cmd = 1; + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + error = VOP_IOCTL(vp, DIOCCACHESYNC, &cmd, + FREAD|FWRITE, kcred); + VOP_UNLOCK(vp, 0); + break; + default: + error = ENOTSUP; + break; + } + break; + case ZIO_TYPE_FREE: + error = VOP_FDISCARD(vp, zio->io_offset, zio->io_size); + break; + default: + error = ENOTSUP; + break; + } bp->b_error = error; vdev_disk_io_intr(bp); } @@ -256,10 +276,11 @@ vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize, */ /* - * Create a workqueue to process cache-flushes concurrently. + * Create a workqueue to process cache-flushes and TRIM + * commands concurrently. */ error = workqueue_create(&dvd->vd_wq, "vdevsync", - vdev_disk_flush, dvd, PRI_NONE, IPL_NONE, WQ_MPSAFE); + vdev_async_cmd, dvd, PRI_NONE, IPL_NONE, WQ_MPSAFE); if (error != 0) { vrele(vp); return (SET_ERROR(error)); @@ -456,37 +477,44 @@ vdev_disk_io_start(zio_t *zio) ASSERT3U(dvd->vd_maxphys, >, 0); vp = dvd->vd_vp; #endif - - if (zio->io_type == ZIO_TYPE_IOCTL) { - /* XXPOLICY */ - if (!vdev_readable(vd)) { - zio->io_error = SET_ERROR(ENXIO); - zio_interrupt(zio); - return; - } - + switch (zio->io_type) { + case ZIO_TYPE_READ: + case ZIO_TYPE_WRITE: + break; + case ZIO_TYPE_IOCTL: switch (zio->io_cmd) { case DKIOCFLUSHWRITECACHE: - - if (zfs_nocacheflush) - break; - + if (zfs_nocacheflush) { + /* XXX Set error? */ + zio_interrupt(zio); + return; + } if (vd->vdev_nowritecache) { - zio->io_error = ENOTSUP; - break; + zio->io_error = SET_ERROR(ENOTSUP); + zio_interrupt(zio); + return; } - - bp = getiobuf(vp, true); - bp->b_private = zio; - workqueue_enqueue(dvd->vd_wq, &bp->b_work, NULL); - return; - + break; default: zio->io_error = SET_ERROR(ENOTSUP); - break; + zio_interrupt(zio); + return; } - - zio_execute(zio); + /*FALLTHROUGH*/ + case ZIO_TYPE_FREE: + /* XXPOLICY */ + if (!vdev_readable(vd)) { + zio->io_error = SET_ERROR(ENXIO); + zio_interrupt(zio); + return; + } + bp = getiobuf(vp, true); + bp->b_private = zio; + workqueue_enqueue(dvd->vd_wq, &bp->b_work, NULL); + return; + default: + zio->io_error = SET_ERROR(ENOTSUP); + zio_interrupt(zio); return; } diff --git a/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c b/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c index e7a6bc79378c..e370b2adfb28 100644 --- a/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c +++ b/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_ioctl.c @@ -7168,9 +7168,6 @@ zfs_modcmd(modcmd_t cmd, void *arg) switch (cmd) { case MODULE_CMD_INIT: - /* XXXNETBSD trim is not supported yet */ - zfs_trim_enabled = B_FALSE; - printf("WARNING: ZFS on NetBSD is under development\n"); availrmem = (uint64_t)physmem * PAGE_SIZE / 1048576; if (availrmem < ZFS_MIN_MEGS * 80 / 100) {