swapoff: add one more variant of the syscall

For MFC, COMPAT_FREEBSD13 braces were removed.

(cherry picked from commit 5346570276)
This commit is contained in:
Konstantin Belousov 2021-12-08 23:04:57 +02:00
parent 79f9a41be0
commit 1791debf4a
8 changed files with 41 additions and 51 deletions

View file

@ -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 *);

View file

@ -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) \

View file

@ -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 {

View file

@ -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

View file

@ -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

View file

@ -197,6 +197,8 @@
RFPROCDESC | RFSPAWN | RFPPWAIT)
#define RFKERNELONLY (RFSTOPPED | RFHIGHPID | RFPROCDESC)
#define SWAPOFF_FORCE 0x00000001
#endif /* __BSD_VISIBLE */
#endif /* !_SYS_UNISTD_H_ */

View file

@ -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)
{

View file

@ -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;