Skip to content

Commit bceb3c4

Browse files
committed
zfs_file: implement zfs_file_deallocate for FreeBSD 14
FreeBSD 14 gained a `VOP_DEALLOCATE` VFS operation and a `fspacectl` syscall to use it. At minimum, these zero the given region, and if the underlying filesystem supports it, can make the region sparse. We can use this to get TRIM-like behaviour for file vdevs. Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris <[email protected]>
1 parent b48232d commit bceb3c4

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

lib/libzpool/kernel.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,6 +1380,12 @@ zfs_file_deallocate(zfs_file_t *fp, loff_t offset, loff_t len)
13801380
#if defined(__linux__)
13811381
rc = fallocate(fp->f_fd,
13821382
FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, offset, len);
1383+
#elif defined(__FreeBSD__) && (__FreeBSD_version >= 1400029)
1384+
struct spacectl_range rqsr = {
1385+
.r_offset = offset,
1386+
.r_len = len,
1387+
};
1388+
rc = fspacectl(fp->f_fd, SPACECTL_DEALLOC, &rqsr, 0, &rqsr);
13831389
#else
13841390
(void) fp, (void) offset, (void) len;
13851391
rc = EOPNOTSUPP;

module/os/freebsd/zfs/zfs_file_os.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,20 @@ zfs_file_fsync(zfs_file_t *fp, int flags)
295295
int
296296
zfs_file_deallocate(zfs_file_t *fp, loff_t offset, loff_t len)
297297
{
298+
int rc;
299+
#if __FreeBSD_version >= 1400029
300+
struct thread *td;
301+
302+
td = curthread;
303+
rc = fo_fspacectl(fp, SPACECTL_DEALLOC, &offset, &len, 0,
304+
td->td_ucred, td);
305+
#else
298306
(void) fp, (void) offset, (void) len;
299-
return (SET_ERROR(EOPNOTSUPP));
307+
rc = EOPNOTSUPP;
308+
#endif
309+
if (rc)
310+
return (SET_ERROR(rc));
311+
return (0);
300312
}
301313

302314
zfs_file_t *

0 commit comments

Comments
 (0)