The branch main has been updated by kib:

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

commit a4e4132fa3bfadb6047fc0fa5f399f4640460300
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2021-11-29 16:26:31 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2021-12-04 22:20:58 +0000

    swapoff(2): replace special device name argument with a structure
    
    For compatibility, add a placeholder pointer to the start of the
    added struct swapoff_new_args, and use it to distinguish old vs. new
    style of syscall invocation.
    
    Reviewed by:    markj
    Discussed with: alc
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D33165
---
 sys/vm/swap_pager.c | 27 +++++++++++++++++++++++++--
 sys/vm/swap_pager.h |  8 ++++++++
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 165373d1b527..dc1df79f4fcd 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -2491,15 +2491,38 @@ sys_swapoff(struct thread *td, struct swapoff_args *uap)
        struct vnode *vp;
        struct nameidata nd;
        struct swdevt *sp;
-       int error;
+       struct swapoff_new_args sa;
+       int error, probe_byte;
 
        error = priv_check(td, PRIV_SWAPOFF);
        if (error)
                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 != 0)
+                       return (EINVAL);
+               break;
+       default:
+               bzero(&sa, sizeof(sa));
+               sa.name = uap->name;
+               break;
+       }
+
        sx_xlock(&swdev_syscall_lock);
 
-       NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE, uap->name);
+       NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE, sa.name);
        error = namei(&nd);
        if (error)
                goto done;
diff --git a/sys/vm/swap_pager.h b/sys/vm/swap_pager.h
index 395fbc9957c4..469de3e8eaf4 100644
--- a/sys/vm/swap_pager.h
+++ b/sys/vm/swap_pager.h
@@ -69,6 +69,14 @@ 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];
+};
+
 #ifdef _KERNEL
 
 extern int swap_pager_avail;

Reply via email to