Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Untangle the swapctl compat code mess. Welcome to lucky 13.



details:   https://anonhg.NetBSD.org/src/rev/8f42324e537c
branches:  trunk
changeset: 360517:8f42324e537c
user:      christos <christos%NetBSD.org@localhost>
date:      Thu Mar 15 00:48:13 2018 +0000

description:
Untangle the swapctl compat code mess. Welcome to lucky 13.

diffstat:

 sys/compat/netbsd32/netbsd32_netbsd.c |   75 +++--------
 sys/sys/param.h                       |    4 +-
 sys/uvm/uvm_swap.c                    |  216 +++++++++++++++++++--------------
 sys/uvm/uvm_swap.h                    |   10 +-
 4 files changed, 153 insertions(+), 152 deletions(-)

diffs (truncated from 459 to 300 lines):

diff -r 39aab4310d54 -r 8f42324e537c sys/compat/netbsd32/netbsd32_netbsd.c
--- a/sys/compat/netbsd32/netbsd32_netbsd.c     Wed Mar 14 23:41:05 2018 +0000
+++ b/sys/compat/netbsd32/netbsd32_netbsd.c     Thu Mar 15 00:48:13 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: netbsd32_netbsd.c,v 1.214 2018/01/09 20:55:43 maya Exp $       */
+/*     $NetBSD: netbsd32_netbsd.c,v 1.215 2018/03/15 00:48:13 christos Exp $   */
 
 /*
  * Copyright (c) 1998, 2001, 2008 Matthew R. Green
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_netbsd.c,v 1.214 2018/01/09 20:55:43 maya Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_netbsd.c,v 1.215 2018/03/15 00:48:13 christos Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ddb.h"
@@ -1718,59 +1718,23 @@
        return (sys___posix_rename(l, &ua, retval));
 }
 
-static int
-netbsd32_swapctl_stats(struct lwp *l, struct sys_swapctl_args *uap, register_t *retval)
+static void
+swapent32_cvt(void *p, const struct swapent *se)
 {
-       struct swapent *ksep;
-       struct netbsd32_swapent *usep32;
-       struct netbsd32_swapent se32;
-       int count = SCARG(uap, misc);
-       int i, error = 0;
-       size_t ksep_len;
-
-       if (count < 0)
-               return EINVAL;
-
-       swapsys_lock(RW_WRITER);
-
-       if ((size_t)count > (size_t)uvmexp.nswapdev)
-               count = uvmexp.nswapdev;
-       if (count == 0) {
-               /* No swap device */
-               swapsys_unlock();
-               return 0;
-       }
-
-       ksep_len = sizeof(*ksep) * count;
-       ksep = kmem_alloc(ksep_len, KM_SLEEP);
-       usep32 = (struct netbsd32_swapent *)SCARG(uap, arg);
-
-       uvm_swap_stats(SWAP_STATS, ksep, count, retval);
-       count = *retval;
-
-       swapsys_unlock();
-
-       for (i = 0; i < count; i++) {
-               se32.se_dev = ksep[i].se_dev;
-               se32.se_flags = ksep[i].se_flags;
-               se32.se_nblks = ksep[i].se_nblks;
-               se32.se_inuse = ksep[i].se_inuse;
-               se32.se_priority = ksep[i].se_priority;
-               memcpy(se32.se_path, ksep[i].se_path,
-                       sizeof(se32.se_path));
-
-               error = copyout(&se32, usep32 + i, sizeof(se32));
-               if (error)
-                       break;
-       }
-
-       kmem_free(ksep, ksep_len);
-
-       return error;
+       struct netbsd32_swapent *se32 = p;
+
+       se32->se_dev = se->se_dev;
+       se32->se_flags = se->se_flags;
+       se32->se_nblks = se->se_nblks;
+       se32->se_inuse = se->se_inuse;
+       se32->se_priority = se->se_priority;
+       KASSERT(sizeof(se->se_path) <= sizeof(se32->se_path));
+       strcpy(se32->se_path, se->se_path);
 }
 
 int
-netbsd32_swapctl(struct lwp *l, const struct netbsd32_swapctl_args *uap, register_t *retval)
+netbsd32_swapctl(struct lwp *l, const struct netbsd32_swapctl_args *uap,
+    register_t *retval)
 {
        /* {
                syscallarg(int) cmd;
@@ -1784,8 +1748,13 @@
        NETBSD32TO64_UAP(misc);
 
        /* SWAP_STATS50 and SWAP_STATS13 structures need no translation */
-       if (SCARG(&ua, cmd) == SWAP_STATS)
-               return netbsd32_swapctl_stats(l, &ua, retval);
+       if (SCARG(&ua, cmd) == SWAP_STATS) {
+               swapsys_lock(RW_READER);
+               int error = uvm_swap_stats(SCARG(&ua, arg), SCARG(&ua, misc),
+                   swapent32_cvt, sizeof(struct netbsd32_swapent), retval);
+               swapsys_unlock();
+               return error;
+       }
 
        return (sys_swapctl(l, &ua, retval));
 }
diff -r 39aab4310d54 -r 8f42324e537c sys/sys/param.h
--- a/sys/sys/param.h   Wed Mar 14 23:41:05 2018 +0000
+++ b/sys/sys/param.h   Thu Mar 15 00:48:13 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: param.h,v 1.557 2018/01/09 19:52:29 christos Exp $     */
+/*     $NetBSD: param.h,v 1.558 2018/03/15 00:48:13 christos Exp $     */
 
 /*-
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -67,7 +67,7 @@
  *     2.99.9          (299000900)
  */
 
-#define        __NetBSD_Version__      899001200       /* NetBSD 8.99.12 */
+#define        __NetBSD_Version__      899001300       /* NetBSD 8.99.13 */
 
 #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
     (m) * 1000000) + (p) * 100) <= __NetBSD_Version__)
diff -r 39aab4310d54 -r 8f42324e537c sys/uvm/uvm_swap.c
--- a/sys/uvm/uvm_swap.c        Wed Mar 14 23:41:05 2018 +0000
+++ b/sys/uvm/uvm_swap.c        Thu Mar 15 00:48:13 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_swap.c,v 1.175 2017/10/28 00:37:13 pgoyette Exp $  */
+/*     $NetBSD: uvm_swap.c,v 1.176 2018/03/15 00:48:13 christos Exp $  */
 
 /*
  * Copyright (c) 1995, 1996, 1997, 2009 Matthew R. Green
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_swap.c,v 1.175 2017/10/28 00:37:13 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_swap.c,v 1.176 2018/03/15 00:48:13 christos Exp $");
 
 #include "opt_uvmhist.h"
 #include "opt_compat_netbsd.h"
@@ -440,6 +440,85 @@
        rw_exit(&swap_syscall_lock);
 }
 
+#if defined(COMPAT_13)
+static void
+swapent13_cvt(void *p, const struct swapent *se)
+{
+       struct swapent13 *sep13 = p;
+
+       sep13->se13_dev = se->se_dev;
+       sep13->se13_flags = se->se_flags;
+       sep13->sse13_nblks = se->se_nblks;
+       sep13->se13_inuse = se->se_inuse;
+       sep13->se13_priority = se->se_priority;
+}
+#endif
+
+#if defined(COMPAT_50)
+static void
+swapent50_cvt(void *p, const struct swapent *se)
+{
+       struct swapent50 *sep50 = p;
+
+       sep50->se50_dev = se->se_dev;
+       sep50->se50_flags = se->se_flags;
+       sep50->se50_nblks = se->se_nblks;
+       sep50->se50_inuse = se->se_inuse;
+       sep50->se50_priority = se->se_priority;
+       KASSERT(sizeof(se->se_path) <= sizeof(sep50->se50_path));
+       strcpy(sep50->se50_path, se->se_path);
+}
+#endif
+
+static void
+swapent_cvt(struct swapent *se, const struct swapdev *sdp, int inuse)
+{
+       se->se_dev = sdp->swd_dev;
+       se->se_flags = sdp->swd_flags;
+       se->se_nblks = sdp->swd_nblks;
+       se->se_inuse = inuse;
+       se->se_priority = sdp->swd_priority;
+       KASSERT(sdp->swd_pathlen < sizeof(se->se_path));
+       strcpy(se->se_path, sdp->swd_path);
+}
+
+static size_t
+swapent_size(int cmd)
+{
+       switch (cmd) {
+#if defined(COMPAT_13)
+       case SWAP_STATS13:
+               return sizeof(struct swapent13);
+#endif
+#if defined(COMPAT_50)
+       case SWAP_STATS50:
+               return sizeof(struct swapent50);
+#endif
+       case SWAP_STATS:
+               return sizeof(struct swapent);
+       default:
+               return 0;
+       }
+}
+
+static void (*
+swapent_fun(int cmd))(void *, const struct swapent *)
+{
+       switch (cmd) {
+#if defined(COMPAT_13)
+       case SWAP_STATS13:
+               return swapent13_cvt;
+#endif
+#if defined(COMPAT_50)
+       case SWAP_STATS50:
+               return swapent50_cvt;
+#endif
+       case SWAP_STATS:
+       default:
+               return NULL;
+       }
+}
+
 /*
  * sys_swapctl: main entry point for swapctl(2) system call
  *     [with two helper functions: swap_on and swap_off]
@@ -456,11 +535,10 @@
        struct nameidata nd;
        struct swappri *spp;
        struct swapdev *sdp;
-       struct swapent *sep;
 #define SWAP_PATH_MAX (PATH_MAX + 1)
        char    *userpath;
        size_t  len = 0;
-       int     error, misc;
+       int     error;
        int     priority;
        UVMHIST_FUNC("sys_swapctl"); UVMHIST_CALLED(pdhist);
 
@@ -478,7 +556,6 @@
                return 0;
        }
 
-       misc = SCARG(uap, misc);
        userpath = kmem_alloc(SWAP_PATH_MAX, KM_SLEEP);
 
        /*
@@ -494,51 +571,25 @@
         * to grab the uvm_swap_data_lock because we may fault&sleep during
         * copyout() and we don't want to be holding that lock then!
         */
-       if (SCARG(uap, cmd) == SWAP_STATS
+       switch (SCARG(uap, cmd)) {
+       case SWAP_STATS:
 #if defined(COMPAT_50)
-           || SCARG(uap, cmd) == SWAP_STATS50
+       case SWAP_STATS50:
 #endif
 #if defined(COMPAT_13)
-           || SCARG(uap, cmd) == SWAP_STATS13
+       case SWAP_STATS13:
 #endif
-           ) {
-               if (misc < 0) {
-                       error = EINVAL;
-                       goto out;
-               }
-               if (misc == 0 || uvmexp.nswapdev == 0) {
-                       error = 0;
-                       goto out;
-               }
-               /* Make sure userland cannot exhaust kernel memory */
-               if ((size_t)misc > (size_t)uvmexp.nswapdev)
-                       misc = uvmexp.nswapdev;
-               KASSERT(misc > 0);
-#if defined(COMPAT_13)
-               if (SCARG(uap, cmd) == SWAP_STATS13)
-                       len = sizeof(struct swapent13) * misc;
-               else
-#endif
-#if defined(COMPAT_50)
-               if (SCARG(uap, cmd) == SWAP_STATS50)
-                       len = sizeof(struct swapent50) * misc;
-               else
-#endif
-                       len = sizeof(struct swapent) * misc;
-               sep = (struct swapent *)kmem_alloc(len, KM_SLEEP);
-
-               uvm_swap_stats(SCARG(uap, cmd), sep, misc, retval);
-               error = copyout(sep, SCARG(uap, arg), len);
-
-               kmem_free(sep, len);
+               error = uvm_swap_stats(SCARG(uap, arg), SCARG(uap, misc),
+                   swapent_fun(SCARG(uap, cmd)), swapent_size(SCARG(uap, cmd)),
+                   retval);
                UVMHIST_LOG(pdhist, "<- done SWAP_STATS", 0, 0, 0, 0);
                goto out;



Home | Main Index | Thread Index | Old Index