Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F136782942
D28347.id83089.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
38 KB
Referenced Files
None
Subscribers
None
D28347.id83089.diff
View Options
Index: lib/libc/sys/Symbol.map
===================================================================
--- lib/libc/sys/Symbol.map
+++ lib/libc/sys/Symbol.map
@@ -407,9 +407,11 @@
aio_writev;
close_range;
copy_file_range;
+ fdeallocate;
fhlink;
fhlinkat;
fhreadlink;
+ fzero;
getfhat;
funlinkat;
memfd_create;
Index: sys/bsm/audit_kevents.h
===================================================================
--- sys/bsm/audit_kevents.h
+++ sys/bsm/audit_kevents.h
@@ -662,6 +662,8 @@
#define AUE_SPECIALFD 43266 /* FreeBSD-specific. */
#define AUE_AIO_WRITEV 43267 /* FreeBSD-specific. */
#define AUE_AIO_READV 43268 /* FreeBSD-specific. */
+#define AUE_FDEALLOCATE 43269 /* FreeBSD-specific. */
+#define AUE_FZERO 43270 /* FreeBSD-specific. */
/*
* Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the
Index: sys/compat/freebsd32/freebsd32_misc.c
===================================================================
--- sys/compat/freebsd32/freebsd32_misc.c
+++ sys/compat/freebsd32/freebsd32_misc.c
@@ -3569,6 +3569,20 @@
return (kern_posix_error(td, error));
}
+int
+freebsd32_fdeallocate(struct thread *td, struct freebsd32_fdeallocate_args *uap)
+{
+ return (kern_fdeallocate(td, uap->fd,
+ PAIR32TO64(off_t, uap->offset), PAIR32TO64(off_t, uap->len)));
+}
+
+int
+freebsd32_fzero(struct thread *td, struct freebsd32_fzero_args *uap)
+{
+ return (kern_fzero(td, uap->fd,
+ PAIR32TO64(off_t, uap->offset), PAIR32TO64(off_t, uap->len)));
+}
+
int
freebsd32_posix_fadvise(struct thread *td,
struct freebsd32_posix_fadvise_args *uap)
Index: sys/compat/freebsd32/freebsd32_proto.h
===================================================================
--- sys/compat/freebsd32/freebsd32_proto.h
+++ sys/compat/freebsd32/freebsd32_proto.h
@@ -751,6 +751,39 @@
struct freebsd32_aio_readv_args {
char aiocbp_l_[PADL_(struct aiocb32 *)]; struct aiocb32 * aiocbp; char aiocbp_r_[PADR_(struct aiocb32 *)];
};
+#ifdef PAD64_REQUIRED
+struct freebsd32_fallocate_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
+ char len1_l_[PADL_(uint32_t)]; uint32_t len1; char len1_r_[PADR_(uint32_t)];
+ char len2_l_[PADL_(uint32_t)]; uint32_t len2; char len2_r_[PADR_(uint32_t)];
+};
+struct freebsd32_fzero_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char pad_l_[PADL_(int)]; int pad; char pad_r_[PADR_(int)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
+ char len1_l_[PADL_(uint32_t)]; uint32_t len1; char len1_r_[PADR_(uint32_t)];
+ char len2_l_[PADL_(uint32_t)]; uint32_t len2; char len2_r_[PADR_(uint32_t)];
+};
+#else
+struct freebsd32_fdeallocate_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
+ char len1_l_[PADL_(uint32_t)]; uint32_t len1; char len1_r_[PADR_(uint32_t)];
+ char len2_l_[PADL_(uint32_t)]; uint32_t len2; char len2_r_[PADR_(uint32_t)];
+};
+struct freebsd32_fzero_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+ char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
+ char len1_l_[PADL_(uint32_t)]; uint32_t len1; char len1_r_[PADR_(uint32_t)];
+ char len2_l_[PADL_(uint32_t)]; uint32_t len2; char len2_r_[PADR_(uint32_t)];
+};
+#endif
#if !defined(PAD64_REQUIRED) && !defined(__amd64__)
#define PAD64_REQUIRED
#endif
@@ -893,6 +926,13 @@
int freebsd32___sysctlbyname(struct thread *, struct freebsd32___sysctlbyname_args *);
int freebsd32_aio_writev(struct thread *, struct freebsd32_aio_writev_args *);
int freebsd32_aio_readv(struct thread *, struct freebsd32_aio_readv_args *);
+#ifdef PAD64_REQUIRED
+int freebsd32_fallocate(struct thread *, struct freebsd32_fallocate_args *);
+int freebsd32_fzero(struct thread *, struct freebsd32_fzero_args *);
+#else
+int freebsd32_fdeallocate(struct thread *, struct freebsd32_fdeallocate_args *);
+int freebsd32_fzero(struct thread *, struct freebsd32_fzero_args *);
+#endif
#ifdef COMPAT_43
@@ -970,6 +1010,9 @@
#ifdef PAD64_REQUIRED
#else
#endif
+#ifdef PAD64_REQUIRED
+#else
+#endif
int ofreebsd32_lseek(struct thread *, struct ofreebsd32_lseek_args *);
int ofreebsd32_stat(struct thread *, struct ofreebsd32_stat_args *);
int ofreebsd32_lstat(struct thread *, struct ofreebsd32_lstat_args *);
@@ -1044,6 +1087,9 @@
#ifdef PAD64_REQUIRED
#else
#endif
+#ifdef PAD64_REQUIRED
+#else
+#endif
int freebsd4_freebsd32_getfsstat(struct thread *, struct freebsd4_freebsd32_getfsstat_args *);
int freebsd4_freebsd32_statfs(struct thread *, struct freebsd4_freebsd32_statfs_args *);
int freebsd4_freebsd32_fstatfs(struct thread *, struct freebsd4_freebsd32_fstatfs_args *);
@@ -1132,6 +1178,9 @@
#ifdef PAD64_REQUIRED
#else
#endif
+#ifdef PAD64_REQUIRED
+#else
+#endif
int freebsd6_freebsd32_pread(struct thread *, struct freebsd6_freebsd32_pread_args *);
int freebsd6_freebsd32_pwrite(struct thread *, struct freebsd6_freebsd32_pwrite_args *);
int freebsd6_freebsd32_mmap(struct thread *, struct freebsd6_freebsd32_mmap_args *);
@@ -1181,6 +1230,9 @@
#ifdef PAD64_REQUIRED
#else
#endif
+#ifdef PAD64_REQUIRED
+#else
+#endif
int freebsd7_freebsd32_semctl(struct thread *, struct freebsd7_freebsd32_semctl_args *);
int freebsd7_freebsd32_msgctl(struct thread *, struct freebsd7_freebsd32_msgctl_args *);
int freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_args *);
@@ -1208,6 +1260,9 @@
#ifdef PAD64_REQUIRED
#else
#endif
+#ifdef PAD64_REQUIRED
+#else
+#endif
int freebsd10_freebsd32_pipe(struct thread *, struct freebsd10_freebsd32_pipe_args *);
#endif /* COMPAT_FREEBSD10 */
@@ -1274,6 +1329,9 @@
#ifdef PAD64_REQUIRED
#else
#endif
+#ifdef PAD64_REQUIRED
+#else
+#endif
int freebsd11_freebsd32_stat(struct thread *, struct freebsd11_freebsd32_stat_args *);
int freebsd11_freebsd32_fstat(struct thread *, struct freebsd11_freebsd32_fstat_args *);
int freebsd11_freebsd32_lstat(struct thread *, struct freebsd11_freebsd32_lstat_args *);
@@ -1306,6 +1364,9 @@
#ifdef PAD64_REQUIRED
#else
#endif
+#ifdef PAD64_REQUIRED
+#else
+#endif
#endif /* COMPAT_FREEBSD12 */
@@ -1476,6 +1537,10 @@
#define FREEBSD32_SYS_AUE_freebsd32___sysctlbyname AUE_SYSCTL
#define FREEBSD32_SYS_AUE_freebsd32_aio_writev AUE_AIO_WRITEV
#define FREEBSD32_SYS_AUE_freebsd32_aio_readv AUE_AIO_READV
+#define FREEBSD32_SYS_AUE_freebsd32_fallocate AUE_FDEALLOCATE
+#define FREEBSD32_SYS_AUE_freebsd32_fzero AUE_FZERO
+#define FREEBSD32_SYS_AUE_freebsd32_fdeallocate AUE_FDEALLOCATE
+#define FREEBSD32_SYS_AUE_freebsd32_fzero AUE_FZERO
#undef PAD_
#undef PADL_
Index: sys/compat/freebsd32/freebsd32_syscall.h
===================================================================
--- sys/compat/freebsd32/freebsd32_syscall.h
+++ sys/compat/freebsd32/freebsd32_syscall.h
@@ -506,4 +506,8 @@
#define FREEBSD32_SYS___specialfd 577
#define FREEBSD32_SYS_freebsd32_aio_writev 578
#define FREEBSD32_SYS_freebsd32_aio_readv 579
-#define FREEBSD32_SYS_MAXSYSCALL 580
+#define FREEBSD32_SYS_freebsd32_fallocate 580
+#define FREEBSD32_SYS_freebsd32_fzero 581
+#define FREEBSD32_SYS_freebsd32_fdeallocate 580
+#define FREEBSD32_SYS_freebsd32_fzero 581
+#define FREEBSD32_SYS_MAXSYSCALL 582
Index: sys/compat/freebsd32/freebsd32_syscalls.c
===================================================================
--- sys/compat/freebsd32/freebsd32_syscalls.c
+++ sys/compat/freebsd32/freebsd32_syscalls.c
@@ -616,4 +616,11 @@
"__specialfd", /* 577 = __specialfd */
"freebsd32_aio_writev", /* 578 = freebsd32_aio_writev */
"freebsd32_aio_readv", /* 579 = freebsd32_aio_readv */
+#ifdef PAD64_REQUIRED
+ "freebsd32_fallocate", /* 580 = freebsd32_fallocate */
+ "freebsd32_fzero", /* 581 = freebsd32_fzero */
+#else
+ "freebsd32_fdeallocate", /* 580 = freebsd32_fdeallocate */
+ "freebsd32_fzero", /* 581 = freebsd32_fzero */
+#endif
};
Index: sys/compat/freebsd32/freebsd32_sysent.c
===================================================================
--- sys/compat/freebsd32/freebsd32_sysent.c
+++ sys/compat/freebsd32/freebsd32_sysent.c
@@ -669,4 +669,11 @@
{ .sy_narg = AS(__specialfd_args), .sy_call = (sy_call_t *)sys___specialfd, .sy_auevent = AUE_SPECIALFD, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 577 = __specialfd */
{ .sy_narg = AS(freebsd32_aio_writev_args), .sy_call = (sy_call_t *)freebsd32_aio_writev, .sy_auevent = AUE_AIO_WRITEV, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 578 = freebsd32_aio_writev */
{ .sy_narg = AS(freebsd32_aio_readv_args), .sy_call = (sy_call_t *)freebsd32_aio_readv, .sy_auevent = AUE_AIO_READV, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 579 = freebsd32_aio_readv */
+#ifdef PAD64_REQUIRED
+ { .sy_narg = AS(freebsd32_fallocate_args), .sy_call = (sy_call_t *)freebsd32_fallocate, .sy_auevent = AUE_FDEALLOCATE, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 580 = freebsd32_fallocate */
+ { .sy_narg = AS(freebsd32_fzero_args), .sy_call = (sy_call_t *)freebsd32_fzero, .sy_auevent = AUE_FZERO, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 581 = freebsd32_fzero */
+#else
+ { .sy_narg = AS(freebsd32_fdeallocate_args), .sy_call = (sy_call_t *)freebsd32_fdeallocate, .sy_auevent = AUE_FDEALLOCATE, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 580 = freebsd32_fdeallocate */
+ { .sy_narg = AS(freebsd32_fzero_args), .sy_call = (sy_call_t *)freebsd32_fzero, .sy_auevent = AUE_FZERO, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 581 = freebsd32_fzero */
+#endif
};
Index: sys/compat/freebsd32/freebsd32_systrace_args.c
===================================================================
--- sys/compat/freebsd32/freebsd32_systrace_args.c
+++ sys/compat/freebsd32/freebsd32_systrace_args.c
@@ -3407,6 +3407,55 @@
*n_args = 1;
break;
}
+#ifdef PAD64_REQUIRED
+ /* freebsd32_fallocate */
+ case 580: {
+ struct freebsd32_fallocate_args *p = params;
+ iarg[0] = p->fd; /* int */
+ iarg[1] = p->pad; /* int */
+ uarg[2] = p->offset1; /* uint32_t */
+ uarg[3] = p->offset2; /* uint32_t */
+ uarg[4] = p->len1; /* uint32_t */
+ uarg[5] = p->len2; /* uint32_t */
+ *n_args = 6;
+ break;
+ }
+ /* freebsd32_fzero */
+ case 581: {
+ struct freebsd32_fzero_args *p = params;
+ iarg[0] = p->fd; /* int */
+ iarg[1] = p->pad; /* int */
+ uarg[2] = p->offset1; /* uint32_t */
+ uarg[3] = p->offset2; /* uint32_t */
+ uarg[4] = p->len1; /* uint32_t */
+ uarg[5] = p->len2; /* uint32_t */
+ *n_args = 6;
+ break;
+ }
+#else
+ /* freebsd32_fdeallocate */
+ case 580: {
+ struct freebsd32_fdeallocate_args *p = params;
+ iarg[0] = p->fd; /* int */
+ uarg[1] = p->offset1; /* uint32_t */
+ uarg[2] = p->offset2; /* uint32_t */
+ uarg[3] = p->len1; /* uint32_t */
+ uarg[4] = p->len2; /* uint32_t */
+ *n_args = 5;
+ break;
+ }
+ /* freebsd32_fzero */
+ case 581: {
+ struct freebsd32_fzero_args *p = params;
+ iarg[0] = p->fd; /* int */
+ uarg[1] = p->offset1; /* uint32_t */
+ uarg[2] = p->offset2; /* uint32_t */
+ uarg[3] = p->len1; /* uint32_t */
+ uarg[4] = p->len2; /* uint32_t */
+ *n_args = 5;
+ break;
+ }
+#endif
default:
*n_args = 0;
break;
@@ -9183,6 +9232,103 @@
break;
};
break;
+#ifdef PAD64_REQUIRED
+ /* freebsd32_fallocate */
+ case 580:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "uint32_t";
+ break;
+ case 3:
+ p = "uint32_t";
+ break;
+ case 4:
+ p = "uint32_t";
+ break;
+ case 5:
+ p = "uint32_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* freebsd32_fzero */
+ case 581:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "int";
+ break;
+ case 2:
+ p = "uint32_t";
+ break;
+ case 3:
+ p = "uint32_t";
+ break;
+ case 4:
+ p = "uint32_t";
+ break;
+ case 5:
+ p = "uint32_t";
+ break;
+ default:
+ break;
+ };
+ break;
+#else
+ /* freebsd32_fdeallocate */
+ case 580:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "uint32_t";
+ break;
+ case 2:
+ p = "uint32_t";
+ break;
+ case 3:
+ p = "uint32_t";
+ break;
+ case 4:
+ p = "uint32_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* freebsd32_fzero */
+ case 581:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "uint32_t";
+ break;
+ case 2:
+ p = "uint32_t";
+ break;
+ case 3:
+ p = "uint32_t";
+ break;
+ case 4:
+ p = "uint32_t";
+ break;
+ default:
+ break;
+ };
+ break;
+#endif
default:
break;
};
@@ -11102,6 +11248,29 @@
if (ndx == 0 || ndx == 1)
p = "int";
break;
+#ifdef PAD64_REQUIRED
+ /* freebsd32_fallocate */
+ case 580:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* freebsd32_fzero */
+ case 581:
+ if (ndx == 0 || ndx == 1)
+ p = "off_t";
+ break;
+#else
+ /* freebsd32_fdeallocate */
+ case 580:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* freebsd32_fzero */
+ case 581:
+ if (ndx == 0 || ndx == 1)
+ p = "off_t";
+ break;
+#endif
default:
break;
};
Index: sys/compat/freebsd32/syscalls.master
===================================================================
--- sys/compat/freebsd32/syscalls.master
+++ sys/compat/freebsd32/syscalls.master
@@ -1174,5 +1174,22 @@
struct aiocb32 *aiocbp); }
579 AUE_AIO_READV STD { int freebsd32_aio_readv( \
struct aiocb32 *aiocbp); }
+#ifdef PAD64_REQUIRED
+580 AUE_FDEALLOCATE STD { int freebsd32_fallocate(int fd, \
+ int pad, \
+ uint32_t offset1, uint32_t offset2,\
+ uint32_t len1, uint32_t len2); }
+581 AUE_FZERO STD { off_t freebsd32_fzero(int fd, \
+ int pad, \
+ uint32_t offset1, uint32_t offset2,\
+ uint32_t len1, uint32_t len2); }
+#else
+580 AUE_FDEALLOCATE STD { int freebsd32_fdeallocate(int fd, \
+ uint32_t offset1, uint32_t offset2,\
+ uint32_t len1, uint32_t len2); }
+581 AUE_FZERO STD { off_t freebsd32_fzero(int fd, \
+ uint32_t offset1, uint32_t offset2,\
+ uint32_t len1, uint32_t len2); }
+#endif
; vim: syntax=off
Index: sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c
===================================================================
--- sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c
+++ sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c
@@ -3797,6 +3797,49 @@
return (error);
}
+/*
+ * common code for zfs_space-related operations
+ *
+ * This function is called from zfs_space and zfs_deallocate.
+ */
+static int
+zfs_space_common(znode_t *zp, int cmd, off_t off, off_t len, int flag,
+ cred_t *cr)
+{
+ zfsvfs_t *zfsvfs = ZTOZSB(zp);
+ uint64_t uoff, ulen;
+ int error;
+
+ if (cmd != F_FREESP)
+ return (EINVAL);
+
+ /*
+ * Callers might not be able to detect properly that we are read-only,
+ * so check it explicitly here.
+ */
+ if (zfs_is_readonly(zfsvfs))
+ return (EROFS);
+
+ if (len < 0)
+ return (EINVAL);
+
+ /*
+ * Permissions aren't checked on Solaris because on this OS
+ * zfs_space() can only be called with an opened file handle.
+ * On Linux we can get here through truncate_range() which
+ * operates directly on inodes, so we need to check access rights.
+ */
+ if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr)))
+ return (error);
+
+ uoff = off;
+ ulen = len;
+
+ error = zfs_freesp(zp, uoff, ulen, flag, TRUE);
+
+ return (error);
+}
+
/*
* Free or allocate space in a file. Currently, this function only
* supports the `F_FREESP' command. However, this command is somewhat
@@ -3821,47 +3864,16 @@
offset_t offset, cred_t *cr)
{
zfsvfs_t *zfsvfs = ZTOZSB(zp);
- uint64_t off, len;
+ off_t off, len;
int error;
ZFS_ENTER(zfsvfs);
ZFS_VERIFY_ZP(zp);
- if (cmd != F_FREESP) {
- ZFS_EXIT(zfsvfs);
- return (SET_ERROR(EINVAL));
- }
-
- /*
- * Callers might not be able to detect properly that we are read-only,
- * so check it explicitly here.
- */
- if (zfs_is_readonly(zfsvfs)) {
- ZFS_EXIT(zfsvfs);
- return (SET_ERROR(EROFS));
- }
-
- if (bfp->l_len < 0) {
- ZFS_EXIT(zfsvfs);
- return (SET_ERROR(EINVAL));
- }
-
- /*
- * Permissions aren't checked on Solaris because on this OS
- * zfs_space() can only be called with an opened file handle.
- * On Linux we can get here through truncate_range() which
- * operates directly on inodes, so we need to check access rights.
- */
- if ((error = zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr))) {
- ZFS_EXIT(zfsvfs);
- return (error);
- }
-
off = bfp->l_start;
len = bfp->l_len; /* 0 means from off to end of file */
- error = zfs_freesp(zp, off, len, flag, TRUE);
-
+ error = zfs_space_common(zp, cmd, off, len, flag, cr);
ZFS_EXIT(zfsvfs);
return (error);
}
@@ -5783,6 +5795,75 @@
return (error);
}
+/*
+ * This is mostly the same as zfs_space except it limits the range of operation
+ * to zp->z_size, so the log record of zfs_space during replay would be reused.
+ */
+static int
+zfs_deallocate(struct vop_deallocate_args *ap)
+{
+ vnode_t *vp;
+ znode_t *zp;
+ zfsvfs_t *zfsvfs;
+ off_t offset, len;
+ uint64_t file_sz;
+ int error;
+
+ vp = ap->a_vp;
+ zp = VTOZ(vp);
+ zfsvfs = ZTOZSB(zp);
+
+ if (ap->a_offset < 0 || ap->a_len < 0)
+ return (EINVAL);
+
+ ZFS_ENTER(zfsvfs);
+ ZFS_VERIFY_ZP(zp);
+
+ offset = ap->a_offset;
+ len = ap->a_len;
+ file_sz = zp->z_size;
+
+ if ((uint64_t)offset + len > file_sz)
+ len = file_sz - offset;
+ if (len <= 0) {
+ error = 0;
+ goto out;
+ }
+ error = zfs_space_common(zp, F_FREESP, offset, len, O_RDWR, ap->a_cred);
+out:
+ ZFS_EXIT(zfsvfs);
+ return (error);
+}
+
+static int
+zfs_zero(struct vop_zero_args *ap)
+{
+ vnode_t *vp;
+ znode_t *zp;
+ flock64_t fl;
+ int error;
+
+ vp = ap->a_vp;
+ zp = VTOZ(vp);
+
+ if (ap->a_offset < 0 || *ap->a_len < 0)
+ return (EINVAL);
+
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = ap->a_offset;
+ fl.l_len = *ap->a_len;
+ if (fl.l_len > OFF_MAX - fl.l_start)
+ fl.l_len = OFF_MAX - fl.l_start;
+ if (fl.l_len == 0)
+ return (0);
+
+ error = zfs_space(zp, F_FREESP, &fl, O_RDWR, ap->a_offset, ap->a_cred);
+ if (error == 0)
+ *ap->a_len = 0;
+ return (error);
+}
+
struct vop_vector zfs_vnodeops;
struct vop_vector zfs_fifoops;
struct vop_vector zfs_shareops;
@@ -5802,6 +5883,8 @@
#endif
.vop_access = zfs_freebsd_access,
.vop_allocate = VOP_EINVAL,
+ .vop_deallocate = zfs_deallocate,
+ .vop_zero = zfs_zero,
.vop_lookup = zfs_cache_lookup,
.vop_cachedlookup = zfs_freebsd_cachedlookup,
.vop_getattr = zfs_freebsd_getattr,
Index: sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c
===================================================================
--- sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c
+++ sys/contrib/openzfs/module/os/freebsd/zfs/zfs_znode.c
@@ -1449,14 +1449,8 @@
error = dmu_free_long_range(zfsvfs->z_os, zp->z_id, off, len);
- if (error == 0) {
- /*
- * In FreeBSD we cannot free block in the middle of a file,
- * but only at the end of a file, so this code path should
- * never happen.
- */
- vnode_pager_setsize(ZTOV(zp), off);
- }
+ if (error == 0)
+ vnode_pager_purge_range(ZTOV(zp), off, off + len);
zfs_rangelock_exit(lr);
Index: sys/kern/init_sysent.c
===================================================================
--- sys/kern/init_sysent.c
+++ sys/kern/init_sysent.c
@@ -635,4 +635,6 @@
{ .sy_narg = AS(__specialfd_args), .sy_call = (sy_call_t *)sys___specialfd, .sy_auevent = AUE_SPECIALFD, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 577 = __specialfd */
{ .sy_narg = AS(aio_writev_args), .sy_call = (sy_call_t *)sys_aio_writev, .sy_auevent = AUE_AIO_WRITEV, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 578 = aio_writev */
{ .sy_narg = AS(aio_readv_args), .sy_call = (sy_call_t *)sys_aio_readv, .sy_auevent = AUE_AIO_READV, .sy_flags = SYF_CAPENABLED, .sy_thrcnt = SY_THR_STATIC }, /* 579 = aio_readv */
+ { .sy_narg = AS(fdeallocate_args), .sy_call = (sy_call_t *)sys_fdeallocate, .sy_auevent = AUE_FDEALLOCATE, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 580 = fdeallocate */
+ { .sy_narg = AS(fzero_args), .sy_call = (sy_call_t *)sys_fzero, .sy_auevent = AUE_FZERO, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 581 = fzero */
};
Index: sys/kern/sys_generic.c
===================================================================
--- sys/kern/sys_generic.c
+++ sys/kern/sys_generic.c
@@ -861,6 +861,86 @@
return (error);
}
+int
+sys_fdeallocate(struct thread *td, struct fdeallocate_args *uap)
+{
+ return (kern_fdeallocate(td, uap->fd, uap->offset, uap->len));
+}
+
+int
+kern_fdeallocate(struct thread *td, int fd, off_t offset, off_t len)
+{
+ struct file *fp;
+ int error;
+
+ AUDIT_ARG_FD(fd);
+ if (offset < 0 || len <= 0)
+ return (EINVAL);
+
+ AUDIT_ARG_FD(fd);
+ error = fget(td, fd, &cap_pwrite_rights, &fp);
+ if (error != 0)
+ return (error);
+ AUDIT_ARG_FILE(td->td_proc, fp);
+ if ((fp->f_ops->fo_flags & DFLAG_SEEKABLE) == 0) {
+ error = ESPIPE;
+ goto out;
+ }
+ if ((fp->f_flag & FWRITE) == 0) {
+ error = EBADF;
+ goto out;
+ }
+
+ error = fo_fdeallocate(fp, offset, len, td->td_ucred, td);
+out:
+ fdrop(fp, td);
+ return (error);
+}
+
+int
+sys_fzero(struct thread *td, struct fzero_args *uap)
+{
+ return (kern_fzero(td, uap->fd, uap->offset, uap->len));
+}
+
+int
+kern_fzero(struct thread *td, int fd, off_t offset, off_t len)
+{
+ struct file *fp;
+ int error;
+ off_t cnt;
+
+ cnt = len;
+
+ AUDIT_ARG_FD(fd);
+ if (offset < 0 || len <= 0)
+ return (EINVAL);
+
+ AUDIT_ARG_FD(fd);
+ error = fget(td, fd, &cap_pwrite_rights, &fp);
+ if (error != 0)
+ return (error);
+ AUDIT_ARG_FILE(td->td_proc, fp);
+ if ((fp->f_ops->fo_flags & DFLAG_SEEKABLE) == 0) {
+ error = ESPIPE;
+ goto out;
+ }
+ if ((fp->f_flag & FWRITE) == 0) {
+ error = EBADF;
+ goto out;
+ }
+
+ error = fo_fzero(fp, offset, &cnt, td->td_ucred, td);
+ if (cnt != len &&
+ (error == ERESTART || error == EINTR || error == EWOULDBLOCK))
+ error = 0;
+ len -= cnt;
+out:
+ fdrop(fp, td);
+ td->td_retval[0] = len;
+ return (error);
+}
+
int
kern_specialfd(struct thread *td, int type, void *arg)
{
Index: sys/kern/syscalls.c
===================================================================
--- sys/kern/syscalls.c
+++ sys/kern/syscalls.c
@@ -586,4 +586,6 @@
"__specialfd", /* 577 = __specialfd */
"aio_writev", /* 578 = aio_writev */
"aio_readv", /* 579 = aio_readv */
+ "fdeallocate", /* 580 = fdeallocate */
+ "fzero", /* 581 = fzero */
};
Index: sys/kern/syscalls.master
===================================================================
--- sys/kern/syscalls.master
+++ sys/kern/syscalls.master
@@ -3258,6 +3258,20 @@
_Inout_ struct aiocb *aiocbp
);
}
+580 AUE_FDEALLOCATE STD {
+ int fdeallocate(
+ int fd,
+ off_t offset,
+ off_t len
+ );
+ }
+581 AUE_FZERO STD {
+ off_t fzero(
+ int fd,
+ off_t offset,
+ off_t len
+ );
+ }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
Index: sys/kern/systrace_args.c
===================================================================
--- sys/kern/systrace_args.c
+++ sys/kern/systrace_args.c
@@ -3399,6 +3399,24 @@
*n_args = 1;
break;
}
+ /* fdeallocate */
+ case 580: {
+ struct fdeallocate_args *p = params;
+ iarg[0] = p->fd; /* int */
+ iarg[1] = p->offset; /* off_t */
+ iarg[2] = p->len; /* off_t */
+ *n_args = 3;
+ break;
+ }
+ /* fzero */
+ case 581: {
+ struct fzero_args *p = params;
+ iarg[0] = p->fd; /* int */
+ iarg[1] = p->offset; /* off_t */
+ iarg[2] = p->len; /* off_t */
+ *n_args = 3;
+ break;
+ }
default:
*n_args = 0;
break;
@@ -9088,6 +9106,38 @@
break;
};
break;
+ /* fdeallocate */
+ case 580:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "off_t";
+ break;
+ case 2:
+ p = "off_t";
+ break;
+ default:
+ break;
+ };
+ break;
+ /* fzero */
+ case 581:
+ switch(ndx) {
+ case 0:
+ p = "int";
+ break;
+ case 1:
+ p = "off_t";
+ break;
+ case 2:
+ p = "off_t";
+ break;
+ default:
+ break;
+ };
+ break;
default:
break;
};
@@ -11034,6 +11084,16 @@
if (ndx == 0 || ndx == 1)
p = "int";
break;
+ /* fdeallocate */
+ case 580:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
+ /* fzero */
+ case 581:
+ if (ndx == 0 || ndx == 1)
+ p = "off_t";
+ break;
default:
break;
};
Index: sys/kern/vfs_default.c
===================================================================
--- sys/kern/vfs_default.c
+++ sys/kern/vfs_default.c
@@ -92,6 +92,7 @@
static int vop_stdgetpages_async(struct vop_getpages_async_args *ap);
static int vop_stdread_pgcache(struct vop_read_pgcache_args *ap);
static int vop_stdstat(struct vop_stat_args *ap);
+static int vop_stdzero(struct vop_zero_args *ap);
/*
* This vnode table stores what we want to do if the filesystem doesn't
@@ -116,6 +117,8 @@
.vop_advlockasync = vop_stdadvlockasync,
.vop_advlockpurge = vop_stdadvlockpurge,
.vop_allocate = vop_stdallocate,
+ .vop_deallocate = VOP_EOPNOTSUPP,
+ .vop_zero = vop_stdzero,
.vop_bmap = vop_stdbmap,
.vop_close = VOP_NULL,
.vop_fsync = VOP_NULL,
@@ -1075,6 +1078,161 @@
return (error);
}
+static int
+vp_zerofill(struct vnode *vp, struct vattr *vap, off_t offset, off_t len,
+ off_t *residp, struct ucred *cred)
+{
+ int iosize;
+ int error = 0;
+ void *buf = NULL;
+ struct iovec aiov;
+ struct uio auio;
+ struct thread *td;
+
+ iosize = vap->va_blocksize;
+ td = curthread;
+
+ if (iosize == 0)
+ iosize = BLKDEV_IOSIZE;
+ if (iosize > MAXPHYS)
+ iosize = MAXPHYS;
+ buf = malloc(iosize, M_TEMP, M_ZERO | M_WAITOK);
+
+ while (len > 0) {
+ int xfersize = iosize;
+ if (offset % iosize != 0)
+ xfersize -= offset % iosize;
+ if (xfersize > len)
+ xfersize = len;
+
+ error = VOP_DEALLOCATE(vp, offset, xfersize, cred);
+ if (error) {
+ if (error != EOPNOTSUPP)
+ break;
+
+ aiov.iov_base = buf;
+ aiov.iov_len = xfersize;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_offset = offset;
+ auio.uio_resid = xfersize;
+ auio.uio_segflg = UIO_SYSSPACE;
+ auio.uio_rw = UIO_WRITE;
+ auio.uio_td = td;
+
+ error = VOP_WRITE(vp, &auio, 0, cred);
+ if (error != 0) {
+ len -= xfersize - auio.uio_resid;
+ break;
+ }
+ }
+
+ len -= xfersize;
+ offset += xfersize;
+ }
+
+ free(buf, M_TEMP);
+ *residp = len;
+ return (error);
+}
+
+static int
+vop_stdzero(struct vop_zero_args *ap)
+{
+ struct vnode *vp;
+ off_t offset, resid;
+ struct ucred *cred;
+ int error;
+ struct vattr va;
+
+ vp = ap->a_vp;
+ offset = ap->a_offset;
+ resid = *ap->a_len;
+ cred = ap->a_cred;
+
+ if (offset < 0 || resid < 0)
+ return (EINVAL);
+ if (offset + resid < offset)
+ return (EOVERFLOW);
+
+ error = VOP_GETATTR(vp, &va, cred);
+ if (error)
+ return (error);
+ if (va.va_size > OFF_MAX)
+ return (EOVERFLOW);
+
+ if ((uint64_t)offset + resid > va.va_size)
+ resid = va.va_size - offset;
+
+ while (resid > 0) {
+ off_t noff;
+ off_t xfersize;
+ off_t rem;
+
+ noff = offset;
+
+ error = vn_bmap_seekhole_locked(vp, FIOSEEKDATA, &noff, cred);
+ if (error) {
+ if (error == ENXIO) {
+ /* No more data region to be filled */
+ error = vn_truncate_locked(
+ vp, offset + resid, false, cred);
+ if (error)
+ goto out;
+ offset += resid;
+ resid = 0;
+ break;
+ }
+ /* XXX: Is it okay to fallback further? */
+ goto out;
+ }
+ KASSERT(noff >= offset, ("FIOSEEKDATA going backward"));
+ if (noff != offset) {
+ xfersize = omin(noff - offset, resid);
+ resid -= xfersize;
+ offset += xfersize;
+ continue;
+ }
+ error = vn_bmap_seekhole_locked(vp, FIOSEEKHOLE, &noff, cred);
+ if (error)
+ goto out;
+
+ xfersize = noff - offset;
+ if (xfersize > resid)
+ xfersize = resid;
+
+ /* Fill zeroes */
+ error = vp_zerofill(vp, &va, offset, xfersize, &rem, cred);
+ if (error) {
+ resid -= xfersize - rem;
+ offset += xfersize - rem;
+ goto out;
+ }
+
+ resid -= xfersize;
+ offset += xfersize;
+ }
+
+ if (offset < ap->a_offset + *ap->a_len) {
+ VATTR_NULL(&va);
+ va.va_size = ap->a_offset + *ap->a_len;
+ error = VOP_SETATTR(vp, &va, cred);
+ if (error)
+ goto out;
+ resid = 0;
+ }
+out:
+ if (*ap->a_len != resid &&
+ (error == ERESTART || error == EINTR || error == EWOULDBLOCK))
+ error = 0;
+
+ if (!error)
+ *ap->a_len = resid;
+ else
+ vn_truncate_locked(vp, va.va_size, false, cred);
+ return (error);
+}
+
int
vop_stdadvise(struct vop_advise_args *ap)
{
Index: sys/kern/vfs_vnops.c
===================================================================
--- sys/kern/vfs_vnops.c
+++ sys/kern/vfs_vnops.c
@@ -106,6 +106,8 @@
static fo_close_t vn_closefile;
static fo_mmap_t vn_mmap;
static fo_fallocate_t vn_fallocate;
+static fo_fdeallocate_t vn_fdeallocate;
+static fo_fzero_t vn_fzero;
struct fileops vnops = {
.fo_read = vn_io_fault,
@@ -123,6 +125,8 @@
.fo_fill_kinfo = vn_fill_kinfo,
.fo_mmap = vn_mmap,
.fo_fallocate = vn_fallocate,
+ .fo_fdeallocate = vn_fdeallocate,
+ .fo_fzero = vn_fzero,
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE
};
@@ -2345,7 +2349,8 @@
}
int
-vn_bmap_seekhole(struct vnode *vp, u_long cmd, off_t *off, struct ucred *cred)
+vn_bmap_seekhole_locked(struct vnode *vp, u_long cmd, off_t *off,
+ struct ucred *cred)
{
struct vattr va;
daddr_t bn, bnp;
@@ -2353,22 +2358,17 @@
off_t noff;
int error;
- KASSERT(cmd == FIOSEEKHOLE || cmd == FIOSEEKDATA,
- ("Wrong command %lu", cmd));
-
- if (vn_lock(vp, LK_SHARED) != 0)
- return (EBADF);
if (vp->v_type != VREG) {
error = ENOTTY;
- goto unlock;
+ goto out;
}
error = VOP_GETATTR(vp, &va, cred);
if (error != 0)
- goto unlock;
+ goto out;
noff = *off;
if (noff >= va.va_size) {
error = ENXIO;
- goto unlock;
+ goto out;
}
bsize = vp->v_mount->mnt_stat.f_iosize;
for (bn = noff / bsize; noff < va.va_size; bn++, noff += bsize -
@@ -2376,14 +2376,14 @@
error = VOP_BMAP(vp, bn, NULL, &bnp, NULL, NULL);
if (error == EOPNOTSUPP) {
error = ENOTTY;
- goto unlock;
+ goto out;
}
if ((bnp == -1 && cmd == FIOSEEKHOLE) ||
(bnp != -1 && cmd == FIOSEEKDATA)) {
noff = bn * bsize;
if (noff < *off)
noff = *off;
- goto unlock;
+ goto out;
}
}
if (noff > va.va_size)
@@ -2391,13 +2391,28 @@
/* noff == va.va_size. There is an implicit hole at the end of file. */
if (cmd == FIOSEEKDATA)
error = ENXIO;
-unlock:
+out:
VOP_UNLOCK(vp);
if (error == 0)
*off = noff;
return (error);
}
+int
+vn_bmap_seekhole(struct vnode *vp, u_long cmd, off_t *off, struct ucred *cred)
+{
+ int error;
+
+ KASSERT(cmd == FIOSEEKHOLE || cmd == FIOSEEKDATA,
+ ("Wrong command %lu", cmd));
+
+ if (vn_lock(vp, LK_SHARED) != 0)
+ return (EBADF);
+ error = vn_bmap_seekhole_locked(vp, cmd, off, cred);
+ VOP_UNLOCK(vp);
+ return (error);
+}
+
int
vn_seek(struct file *fp, off_t offset, int whence, struct thread *td)
{
@@ -3339,6 +3354,84 @@
return (error);
}
+static int
+vn_fdeallocate(struct file *fp, off_t offset, off_t len,
+ struct ucred *active_cred, struct thread *td)
+{
+ int error;
+ struct mount *mp;
+ struct vnode *vp;
+ int lock_flags;
+ void *rl_cookie = NULL;
+
+ vp = fp->f_vnode;
+
+ if (offset < 0 || len < 0)
+ return (EINVAL);
+ if (vp->v_type != VREG)
+ return (ENODEV);
+
+ /* Take the maximum range if len equals 0 or end offset overflows */
+ if (len == 0 || len > OFF_MAX - offset)
+ len = OFF_MAX - offset;
+ if (len == 0)
+ return (0);
+
+ rl_cookie = vn_rangelock_wlock(vp, offset, offset + len);
+ if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
+ goto out;
+
+ if (MNT_SHARED_WRITES(mp) ||
+ (mp == NULL && MNT_SHARED_WRITES(vp->v_mount))) {
+ lock_flags = LK_SHARED;
+ } else {
+ lock_flags = LK_EXCLUSIVE;
+ }
+ vn_lock(vp, lock_flags | LK_RETRY);
+
+ error = VOP_DEALLOCATE(vp, offset, len, active_cred);
+ VOP_UNLOCK(vp);
+ vn_finished_write(mp);
+
+out:
+ vn_rangelock_unlock(vp, rl_cookie);
+ return (error);
+}
+
+static int
+vn_fzero(struct file *fp, off_t offset, off_t *residp,
+ struct ucred *active_cred, struct thread *td)
+{
+ int error;
+ struct mount *mp;
+ struct vnode *vp;
+ void *rl_cookie = NULL;
+ off_t resid;
+
+ vp = fp->f_vnode;
+ resid = *residp;
+
+ if (offset + resid < offset)
+ return (EOVERFLOW);
+
+ if (vp->v_type != VREG)
+ return (ENODEV);
+
+ rl_cookie = vn_rangelock_wlock(vp, offset, offset + resid);
+ if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
+ goto out;
+
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ error = VOP_ZERO(vp, offset, &resid, active_cred);
+ VOP_UNLOCK(vp);
+ vn_finished_write(mp);
+
+out:
+ *residp = resid;
+ vn_rangelock_unlock(vp, rl_cookie);
+ return (error);
+}
+
static u_long vn_lock_pair_pause_cnt;
SYSCTL_ULONG(_debug, OID_AUTO, vn_lock_pair_pause, CTLFLAG_RD,
&vn_lock_pair_pause_cnt, 0,
Index: sys/kern/vnode_if.src
===================================================================
--- sys/kern/vnode_if.src
+++ sys/kern/vnode_if.src
@@ -706,6 +706,26 @@
};
+%% deallocate vp L L L
+
+vop_deallocate {
+ IN struct vnode *vp;
+ IN off_t offset;
+ IN off_t len;
+ IN struct ucred *cred;
+};
+
+
+%% zero vp L L L
+
+vop_zero {
+ IN struct vnode *vp;
+ IN off_t offset;
+ INOUT off_t *len;
+ IN struct ucred *cred;
+};
+
+
%% advise vp U U U
vop_advise {
Index: sys/security/audit/audit_bsm.c
===================================================================
--- sys/security/audit/audit_bsm.c
+++ sys/security/audit/audit_bsm.c
@@ -1019,12 +1019,14 @@
* XXXRW: Some of these need to handle non-vnode cases as well.
*/
case AUE_FCHDIR:
+ case AUE_FDEALLOCATE:
case AUE_FPATHCONF:
case AUE_FSTAT:
case AUE_FSTATFS:
case AUE_FSYNC:
case AUE_FTRUNCATE:
case AUE_FUTIMES:
+ case AUE_FZERO:
case AUE_GETDIRENTRIES:
case AUE_GETDIRENTRIESATTR:
case AUE_LSEEK:
Index: sys/sys/fcntl.h
===================================================================
--- sys/sys/fcntl.h
+++ sys/sys/fcntl.h
@@ -360,6 +360,8 @@
int posix_fadvise(int, off_t, off_t, int);
int posix_fallocate(int, off_t, off_t);
#endif
+int fdeallocate(int, off_t, off_t);
+off_t fzero(int, off_t, off_t);
__END_DECLS
#endif
Index: sys/sys/file.h
===================================================================
--- sys/sys/file.h
+++ sys/sys/file.h
@@ -129,6 +129,10 @@
typedef int fo_get_seals_t(struct file *fp, int *flags);
typedef int fo_fallocate_t(struct file *fp, off_t offset, off_t len,
struct thread *td);
+typedef int fo_fdeallocate_t(struct file *fp, off_t offset, off_t len,
+ struct ucred *active_cred, struct thread *td);
+typedef int fo_fzero_t(struct file *fp, off_t offset, off_t *residp,
+ struct ucred *active_cred, struct thread *td);
typedef int fo_flags_t;
struct fileops {
@@ -150,6 +154,8 @@
fo_add_seals_t *fo_add_seals;
fo_get_seals_t *fo_get_seals;
fo_fallocate_t *fo_fallocate;
+ fo_fdeallocate_t *fo_fdeallocate;
+ fo_fzero_t *fo_fzero;
fo_flags_t fo_flags; /* DFLAG_* below */
};
@@ -470,6 +476,27 @@
return ((*fp->f_ops->fo_fallocate)(fp, offset, len, td));
}
+static __inline int fo_fdeallocate(struct file *fp, off_t offset, off_t len,
+ struct ucred *active_cred, struct thread *td)
+{
+
+ if (fp->f_ops->fo_fdeallocate == NULL)
+ return (ENODEV);
+ return ((*fp->f_ops->fo_fdeallocate)(fp, offset, len, active_cred,
+ td));
+}
+
+static __inline int fo_fzero(struct file *fp, off_t offset, off_t *residp,
+ struct ucred *active_cred, struct thread *td)
+{
+
+ if (fp->f_ops->fo_fzero == NULL)
+ return (ENODEV);
+ return ((*fp->f_ops->fo_fzero)(fp, offset, residp, active_cred,
+ td));
+}
+
+
#endif /* _KERNEL */
#endif /* !SYS_FILE_H */
Index: sys/sys/syscall.h
===================================================================
--- sys/sys/syscall.h
+++ sys/sys/syscall.h
@@ -515,4 +515,6 @@
#define SYS___specialfd 577
#define SYS_aio_writev 578
#define SYS_aio_readv 579
-#define SYS_MAXSYSCALL 580
+#define SYS_fdeallocate 580
+#define SYS_fzero 581
+#define SYS_MAXSYSCALL 582
Index: sys/sys/syscall.mk
===================================================================
--- sys/sys/syscall.mk
+++ sys/sys/syscall.mk
@@ -420,4 +420,6 @@
rpctls_syscall.o \
__specialfd.o \
aio_writev.o \
- aio_readv.o
+ aio_readv.o \
+ fdeallocate.o \
+ fzero.o
Index: sys/sys/syscallsubr.h
===================================================================
--- sys/sys/syscallsubr.h
+++ sys/sys/syscallsubr.h
@@ -230,6 +230,8 @@
int advice);
int kern_posix_fallocate(struct thread *td, int fd, off_t offset,
off_t len);
+int kern_fdeallocate(struct thread *td, int fd, off_t offset, off_t len);
+int kern_fzero(struct thread *td, int fd, off_t offset, off_t len);
int kern_procctl(struct thread *td, enum idtype idtype, id_t id, int com,
void *data);
int kern_pread(struct thread *td, int fd, void *buf, size_t nbyte,
Index: sys/sys/sysproto.h
===================================================================
--- sys/sys/sysproto.h
+++ sys/sys/sysproto.h
@@ -1847,6 +1847,16 @@
struct aio_readv_args {
char aiocbp_l_[PADL_(struct aiocb *)]; struct aiocb * aiocbp; char aiocbp_r_[PADR_(struct aiocb *)];
};
+struct fdeallocate_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char offset_l_[PADL_(off_t)]; off_t offset; char offset_r_[PADR_(off_t)];
+ char len_l_[PADL_(off_t)]; off_t len; char len_r_[PADR_(off_t)];
+};
+struct fzero_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char offset_l_[PADL_(off_t)]; off_t offset; char offset_r_[PADR_(off_t)];
+ char len_l_[PADL_(off_t)]; off_t len; char len_r_[PADR_(off_t)];
+};
int nosys(struct thread *, struct nosys_args *);
void sys_sys_exit(struct thread *, struct sys_exit_args *);
int sys_fork(struct thread *, struct fork_args *);
@@ -2241,6 +2251,8 @@
int sys___specialfd(struct thread *, struct __specialfd_args *);
int sys_aio_writev(struct thread *, struct aio_writev_args *);
int sys_aio_readv(struct thread *, struct aio_readv_args *);
+int sys_fdeallocate(struct thread *, struct fdeallocate_args *);
+int sys_fzero(struct thread *, struct fzero_args *);
#ifdef COMPAT_43
@@ -3175,6 +3187,8 @@
#define SYS_AUE___specialfd AUE_SPECIALFD
#define SYS_AUE_aio_writev AUE_AIO_WRITEV
#define SYS_AUE_aio_readv AUE_AIO_READV
+#define SYS_AUE_fdeallocate AUE_FDEALLOCATE
+#define SYS_AUE_fzero AUE_FZERO
#undef PAD_
#undef PADL_
Index: sys/sys/vnode.h
===================================================================
--- sys/sys/vnode.h
+++ sys/sys/vnode.h
@@ -719,6 +719,9 @@
void vn_printf(struct vnode *vp, const char *fmt, ...) __printflike(2,3);
int vrecycle(struct vnode *vp);
int vrecyclel(struct vnode *vp);
+/* vn_bmap_seekhole_locked is not public KPI */
+int vn_bmap_seekhole_locked(struct vnode *vp, u_long cmd, off_t *off,
+ struct ucred *cred);
int vn_bmap_seekhole(struct vnode *vp, u_long cmd, off_t *off,
struct ucred *cred);
int vn_close(struct vnode *vp,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Nov 20, 12:38 PM (2 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25725886
Default Alt Text
D28347.id83089.diff (38 KB)
Attached To
Mode
D28347: Add fspacectl(2), vn_deallocate(9) and VOP_DEALLOCATE(9).
Attached
Detach File
Event Timeline
Log In to Comment