diff --git a/include/unistd.h b/include/unistd.h index 5f358ad72d9a..8e44e472c6d6 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -579,7 +579,7 @@ int setruid(uid_t); void setusershell(void); int strtofflags(char **, u_long *, u_long *); int swapon(const char *); -int swapoff(const char *); +int swapoff(const char *, u_int); int syscall(int, ...); off_t __syscall(quad_t, ...); int undelete(const char *); diff --git a/lib/libc/include/compat.h b/lib/libc/include/compat.h index ccb92c0fd930..e6bc2e7a6612 100644 --- a/lib/libc/include/compat.h +++ b/lib/libc/include/compat.h @@ -69,6 +69,8 @@ __sym_compat(mknodat, freebsd11_mknodat, FBSD_1.1); __sym_compat(kevent, freebsd11_kevent, FBSD_1.0); +__sym_compat(swapoff, freebsd13_swapoff, FBSD_1.0); + #undef __sym_compat #define __weak_reference(sym,alias) \ diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map index 80bb2c236191..0c446cca95d4 100644 --- a/lib/libc/sys/Symbol.map +++ b/lib/libc/sys/Symbol.map @@ -260,7 +260,6 @@ FBSD_1.0 { sigwaitinfo; socket; socketpair; - swapoff; swapon; symlink; sync; @@ -419,6 +418,7 @@ FBSD_1.6 { FBSD_1.7 { _Fork; + swapoff; }; FBSDprivate_1.0 { diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index aac788bf3956..1a356bf2832e 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -774,7 +774,7 @@ 423 AUE_NULL STD { int freebsd32_swapcontext( \ struct freebsd32_ucontext *oucp, \ const struct freebsd32_ucontext *ucp); } -424 AUE_SWAPOFF UNIMPL swapoff +424 AUE_SWAPOFF UNIMPL freebsd13_swapoff 425 AUE_ACL_GET_LINK NOPROTO { int __acl_get_link(const char *path, \ acl_type_t type, struct acl *aclp); } 426 AUE_ACL_SET_LINK NOPROTO { int __acl_set_link(const char *path, \ @@ -1176,5 +1176,7 @@ struct aiocb32 *aiocbp); } 579 AUE_AIO_READV STD { int freebsd32_aio_readv( \ struct aiocb32 *aiocbp); } - +580 AUE_NULL UNIMPL fspacectl +581 AUE_NULL UNIMPL sched_getcpu +582 AUE_NULL UNIMPL swapoff ; vim: syntax=off diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 51ff07f8deed..141da7eb7fc5 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -2231,7 +2231,7 @@ ); } 424 AUE_SWAPOFF STD { - int swapoff( + int freebsd13_swapoff( _In_z_ const char *name ); } @@ -3273,6 +3273,14 @@ _Inout_ struct aiocb *aiocbp ); } +580 AUE_NULL UNIMPL fspacectl +581 AUE_NULL UNIMPL sched_getcpu +582 AUE_SWAPOFF STD { + int swapoff( + _In_z_ const char *name, + u_int flags, + ); + } ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master diff --git a/sys/sys/unistd.h b/sys/sys/unistd.h index 3b3de3aa33bc..2d9544652f91 100644 --- a/sys/sys/unistd.h +++ b/sys/sys/unistd.h @@ -197,6 +197,8 @@ RFPROCDESC | RFSPAWN | RFPPWAIT) #define RFKERNELONLY (RFSTOPPED | RFHIGHPID | RFPROCDESC) +#define SWAPOFF_FORCE 0x00000001 + #endif /* __BSD_VISIBLE */ #endif /* !_SYS_UNISTD_H_ */ diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index 9238ecd5645d..3725fc87379f 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -100,6 +100,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -2473,51 +2474,24 @@ swaponsomething(struct vnode *vp, void *id, u_long nblks, * rather than filename as specification. We keep sw_vp around * only to make this work. */ -#ifndef _SYS_SYSPROTO_H_ -struct swapoff_args { - char *name; -}; -#endif - -int -sys_swapoff(struct thread *td, struct swapoff_args *uap) +static int +kern_swapoff(struct thread *td, const char *name, enum uio_seg name_seg, + u_int flags) { struct vnode *vp; struct nameidata nd; struct swdevt *sp; - struct swapoff_new_args sa; - int error, probe_byte; + int error; error = priv_check(td, PRIV_SWAPOFF); - if (error) + if (error != 0) return (error); - - /* - * Detect old vs. new-style swapoff(2) syscall. The first - * pointer in the memory pointed to by uap->name is NULL for - * the new variant. - */ - probe_byte = fubyte(uap->name); - switch (probe_byte) { - case -1: - return (EFAULT); - case 0: - error = copyin(uap->name, &sa, sizeof(sa)); - if (error != 0) - return (error); - if ((sa.flags & ~(SWAPOFF_FORCE)) != 0) - return (EINVAL); - break; - default: - bzero(&sa, sizeof(sa)); - sa.name = uap->name; - break; - } + if ((flags & ~(SWAPOFF_FORCE)) != 0) + return (EINVAL); sx_xlock(&swdev_syscall_lock); - NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE, sa.name, - td); + NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, name_seg, name, td); error = namei(&nd); if (error) goto done; @@ -2534,12 +2508,24 @@ sys_swapoff(struct thread *td, struct swapoff_args *uap) error = EINVAL; goto done; } - error = swapoff_one(sp, td->td_ucred, sa.flags); + error = swapoff_one(sp, td->td_ucred, flags); done: sx_xunlock(&swdev_syscall_lock); return (error); } +int +freebsd13_swapoff(struct thread *td, struct freebsd13_swapoff_args *uap) +{ + return (kern_swapoff(td, uap->name, UIO_USERSPACE, 0)); +} + +int +sys_swapoff(struct thread *td, struct swapoff_args *uap) +{ + return (kern_swapoff(td, uap->name, UIO_USERSPACE, uap->flags)); +} + static int swapoff_one(struct swdevt *sp, struct ucred *cred, u_int flags) { diff --git a/sys/vm/swap_pager.h b/sys/vm/swap_pager.h index b78ac6a7c698..6761d4f99ee4 100644 --- a/sys/vm/swap_pager.h +++ b/sys/vm/swap_pager.h @@ -68,16 +68,6 @@ struct swdevt { #define SW_UNMAPPED 0x01 #define SW_CLOSING 0x04 -struct swapoff_new_args { - const char *name_old_syscall; - const char *name; - u_int flags; - u_int pad0; - uintptr_t pad1[8]; -}; - -#define SWAPOFF_FORCE 0x00000001 - #ifdef _KERNEL extern int swap_pager_avail;