diff options
Diffstat (limited to 'module/zfs/vdev_file.c')
-rw-r--r-- | module/zfs/vdev_file.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/module/zfs/vdev_file.c b/module/zfs/vdev_file.c index 3551898e0..c04f40ca4 100644 --- a/module/zfs/vdev_file.c +++ b/module/zfs/vdev_file.c @@ -28,10 +28,13 @@ #include <sys/spa_impl.h> #include <sys/vdev_file.h> #include <sys/vdev_impl.h> +#include <sys/vdev_trim.h> #include <sys/zio.h> #include <sys/fs/zfs.h> #include <sys/fm/fs/zfs.h> #include <sys/abd.h> +#include <sys/fcntl.h> +#include <sys/vnode.h> /* * Virtual device vector for files. @@ -60,10 +63,25 @@ vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize, vattr_t vattr; int error; - /* Rotational optimizations only make sense on block devices */ + /* + * Rotational optimizations only make sense on block devices. + */ vd->vdev_nonrot = B_TRUE; /* + * Allow TRIM on file based vdevs. This may not always be supported, + * since it depends on your kernel version and underlying filesystem + * type but it is always safe to attempt. + */ + vd->vdev_has_trim = B_TRUE; + + /* + * Disable secure TRIM on file based vdevs. There is no way to + * request this behavior from the underlying filesystem. + */ + vd->vdev_has_securetrim = B_FALSE; + + /* * We must have a pathname, and it must be absolute. */ if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') { @@ -229,6 +247,21 @@ vdev_file_io_start(zio_t *zio) zio_execute(zio); return; + } else if (zio->io_type == ZIO_TYPE_TRIM) { + struct flock flck; + + ASSERT3U(zio->io_size, !=, 0); + bzero(&flck, sizeof (flck)); + flck.l_type = F_FREESP; + flck.l_start = zio->io_offset; + flck.l_len = zio->io_size; + flck.l_whence = 0; + + zio->io_error = VOP_SPACE(vf->vf_vnode, F_FREESP, &flck, + 0, 0, kcred, NULL); + + zio_execute(zio); + return; } zio->io_target_timestamp = zio_handle_io_delay(zio); |