git: 1791debf4ab0 - stable/13 - swapoff: add one more variant of the syscall

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Mon, 20 Dec 2021 00:38:10 UTC
The branch stable/13 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=1791debf4ab08fea14d2ba9997fcff64b70e536a

commit 1791debf4ab08fea14d2ba9997fcff64b70e536a
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-12-08 21:04:57 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-12-20 00:29:11 +0000

    swapoff: add one more variant of the syscall
    
    For MFC, COMPAT_FREEBSD13 braces were removed.
    
    (cherry picked from commit 5346570276a5ddfd5f530201fcbf24ddcc53033d)
---
 include/unistd.h                     |  2 +-
 lib/libc/include/compat.h            |  2 ++
 lib/libc/sys/Symbol.map              |  2 +-
 sys/compat/freebsd32/syscalls.master |  6 ++--
 sys/kern/syscalls.master             | 10 ++++++-
 sys/sys/unistd.h                     |  2 ++
 sys/vm/swap_pager.c                  | 58 ++++++++++++++----------------------
 sys/vm/swap_pager.h                  | 10 -------
 8 files changed, 41 insertions(+), 51 deletions(-)

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 <sys/sysproto.h>
 #include <sys/systm.h>
 #include <sys/sx.h>
+#include <sys/unistd.h>
 #include <sys/user.h>
 #include <sys/vmmeter.h>
 #include <sys/vnode.h>
@@ -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;