Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vdev_file: implement TRIM-like support for FreeBSD 14 #16496

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/sys/zfs_file.h
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ int zfs_file_pread(zfs_file_t *fp, void *buf, size_t len, loff_t off,
int zfs_file_seek(zfs_file_t *fp, loff_t *offp, int whence);
int zfs_file_getattr(zfs_file_t *fp, zfs_file_attr_t *zfattr);
int zfs_file_fsync(zfs_file_t *fp, int flags);
int zfs_file_fallocate(zfs_file_t *fp, int mode, loff_t offset, loff_t len);
int zfs_file_deallocate(zfs_file_t *fp, loff_t offset, loff_t len);
loff_t zfs_file_off(zfs_file_t *fp);
int zfs_file_unlink(const char *);

30 changes: 19 additions & 11 deletions lib/libzpool/kernel.c
Original file line number Diff line number Diff line change
@@ -1367,24 +1367,32 @@ zfs_file_fsync(zfs_file_t *fp, int flags)
}

/*
* fallocate - allocate or free space on disk
* deallocate - zero and/or deallocate file storage
*
* fp - file pointer
* mode (non-standard options for hole punching etc)
* offset - offset to start allocating or freeing from
* len - length to free / allocate
*
* OPTIONAL
* offset - offset to start zeroing or deallocating
* len - length to zero or deallocate
*/
int
zfs_file_fallocate(zfs_file_t *fp, int mode, loff_t offset, loff_t len)
zfs_file_deallocate(zfs_file_t *fp, loff_t offset, loff_t len)
{
#ifdef __linux__
return (fallocate(fp->f_fd, mode, offset, len));
int rc;
#if defined(__linux__)
rc = fallocate(fp->f_fd,
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, offset, len);
#elif defined(__FreeBSD__) && (__FreeBSD_version >= 1400029)
struct spacectl_range rqsr = {
.r_offset = offset,
.r_len = len,
};
rc = fspacectl(fp->f_fd, SPACECTL_DEALLOC, &rqsr, 0, &rqsr);
#else
(void) fp, (void) mode, (void) offset, (void) len;
return (EOPNOTSUPP);
(void) fp, (void) offset, (void) len;
rc = EOPNOTSUPP;
#endif
if (rc)
return (SET_ERROR(rc));
return (0);
}

/*
11 changes: 2 additions & 9 deletions module/os/freebsd/zfs/vdev_file.c
Original file line number Diff line number Diff line change
@@ -260,16 +260,9 @@ vdev_file_io_start(zio_t *zio)
zio_execute(zio);
return;
} else if (zio->io_type == ZIO_TYPE_TRIM) {
#ifdef notyet
int mode = 0;

ASSERT3U(zio->io_size, !=, 0);

/* XXX FreeBSD has no fallocate routine in file ops */
zio->io_error = zfs_file_fallocate(vf->vf_file,
mode, zio->io_offset, zio->io_size);
#endif
zio->io_error = SET_ERROR(ENOTSUP);
zio->io_error = zfs_file_deallocate(vf->vf_file,
zio->io_offset, zio->io_size);
zio_execute(zio);
behlendorf marked this conversation as resolved.
Show resolved Hide resolved
return;
}
26 changes: 26 additions & 0 deletions module/os/freebsd/zfs/zfs_file_os.c
Original file line number Diff line number Diff line change
@@ -285,6 +285,32 @@ zfs_file_fsync(zfs_file_t *fp, int flags)
return (zfs_vop_fsync(fp->f_vnode));
}

/*
* deallocate - zero and/or deallocate file storage
*
* fp - file pointer
* offset - offset to start zeroing or deallocating
* len - length to zero or deallocate
*/
int
zfs_file_deallocate(zfs_file_t *fp, loff_t offset, loff_t len)
{
int rc;
#if __FreeBSD_version >= 1400029
struct thread *td;

td = curthread;
rc = fo_fspacectl(fp, SPACECTL_DEALLOC, &offset, &len, 0,
td->td_ucred, td);
#else
(void) fp, (void) offset, (void) len;
rc = EOPNOTSUPP;
#endif
if (rc)
return (SET_ERROR(rc));
return (0);
}

zfs_file_t *
zfs_file_get(int fd)
{
9 changes: 2 additions & 7 deletions module/os/linux/zfs/vdev_file.c
Original file line number Diff line number Diff line change
@@ -274,14 +274,9 @@ vdev_file_io_start(zio_t *zio)
zio_execute(zio);
return;
} else if (zio->io_type == ZIO_TYPE_TRIM) {
int mode = 0;

ASSERT3U(zio->io_size, !=, 0);
#ifdef __linux__
mode = FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE;
#endif
zio->io_error = zfs_file_fallocate(vf->vf_file,
mode, zio->io_offset, zio->io_size);
zio->io_error = zfs_file_deallocate(vf->vf_file,
zio->io_offset, zio->io_size);
zio_execute(zio);
return;
}
19 changes: 10 additions & 9 deletions module/os/linux/zfs/zfs_file_os.c
Original file line number Diff line number Diff line change
@@ -328,17 +328,14 @@ zfs_file_fsync(zfs_file_t *filp, int flags)
}

/*
* fallocate - allocate or free space on disk
* deallocate - zero and/or deallocate file storage
*
* fp - file pointer
* mode (non-standard options for hole punching etc)
* offset - offset to start allocating or freeing from
* len - length to free / allocate
*
* OPTIONAL
* offset - offset to start zeroing or deallocating
* len - length to zero or deallocate
*/
int
zfs_file_fallocate(zfs_file_t *fp, int mode, loff_t offset, loff_t len)
zfs_file_deallocate(zfs_file_t *fp, loff_t offset, loff_t len)
{
/*
* May enter XFS which generates a warning when PF_FSTRANS is set.
@@ -354,12 +351,16 @@ zfs_file_fallocate(zfs_file_t *fp, int mode, loff_t offset, loff_t len)
*/
int error = EOPNOTSUPP;
if (fp->f_op->fallocate)
error = fp->f_op->fallocate(fp, mode, offset, len);
error = -fp->f_op->fallocate(fp,
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, offset, len);

robn marked this conversation as resolved.
Show resolved Hide resolved
if (fstrans)
current->flags |= __SPL_PF_FSTRANS;

return (error);
if (error)
return (SET_ERROR(error));

return (0);
}

/*
Loading