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 a70d14b51f7c..7984f54da697 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; @@ -420,6 +419,7 @@ FBSD_1.6 { FBSD_1.7 { _Fork; fspacectl; + swapoff; }; FBSDprivate_1.0 { diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 27baced56b7c..38505b3ea012 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -2247,7 +2247,7 @@ _In_ _Contains_long_ptr_ const struct __ucontext *ucp ); } -424 AUE_SWAPOFF STD { +424 AUE_SWAPOFF COMPAT13 { int swapoff( _In_z_ const char *name ); @@ -3300,6 +3300,13 @@ int sched_getcpu(void); } +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 ; vim: syntax=off diff --git a/sys/sys/unistd.h b/sys/sys/unistd.h index ef8835a812d2..be71edbd6e23 100644 --- a/sys/sys/unistd.h +++ b/sys/sys/unistd.h @@ -198,6 +198,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 99addb2c8e53..01cf9233329f 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 @@ -2479,50 +2480,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); + NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, name_seg, name); error = namei(&nd); if (error) goto done; @@ -2539,12 +2514,27 @@ 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); } + +#ifdef COMPAT_FREEBSD13 +int +freebsd13_swapoff(struct thread *td, struct freebsd13_swapoff_args *uap) +{ + return (kern_swapoff(td, uap->name, UIO_USERSPACE, 0)); +} +#endif + +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 59322d49cbc9..395fbc9957c4 100644 --- a/sys/vm/swap_pager.h +++ b/sys/vm/swap_pager.h @@ -69,16 +69,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;