Module Name: src
Committed By: christos
Date: Thu Mar 15 00:48:13 UTC 2018
Modified Files:
src/sys/compat/netbsd32: netbsd32_netbsd.c
src/sys/sys: param.h
src/sys/uvm: uvm_swap.c uvm_swap.h
Log Message:
Untangle the swapctl compat code mess. Welcome to lucky 13.
To generate a diff of this commit:
cvs rdiff -u -r1.214 -r1.215 src/sys/compat/netbsd32/netbsd32_netbsd.c
cvs rdiff -u -r1.557 -r1.558 src/sys/sys/param.h
cvs rdiff -u -r1.175 -r1.176 src/sys/uvm/uvm_swap.c
cvs rdiff -u -r1.22 -r1.23 src/sys/uvm/uvm_swap.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/compat/netbsd32/netbsd32_netbsd.c
diff -u src/sys/compat/netbsd32/netbsd32_netbsd.c:1.214 src/sys/compat/netbsd32/netbsd32_netbsd.c:1.215
--- src/sys/compat/netbsd32/netbsd32_netbsd.c:1.214 Tue Jan 9 15:55:43 2018
+++ src/sys/compat/netbsd32/netbsd32_netbsd.c Wed Mar 14 20:48:13 2018
@@ -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 @@ netbsd32___posix_rename(struct lwp *l, c
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));
+ struct netbsd32_swapent *se32 = p;
- error = copyout(&se32, usep32 + i, sizeof(se32));
- if (error)
- break;
- }
-
- kmem_free(ksep, ksep_len);
-
- return error;
+ 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 @@ netbsd32_swapctl(struct lwp *l, const st
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));
}
Index: src/sys/sys/param.h
diff -u src/sys/sys/param.h:1.557 src/sys/sys/param.h:1.558
--- src/sys/sys/param.h:1.557 Tue Jan 9 14:52:29 2018
+++ src/sys/sys/param.h Wed Mar 14 20:48:13 2018
@@ -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__)
Index: src/sys/uvm/uvm_swap.c
diff -u src/sys/uvm/uvm_swap.c:1.175 src/sys/uvm/uvm_swap.c:1.176
--- src/sys/uvm/uvm_swap.c:1.175 Fri Oct 27 20:37:13 2017
+++ src/sys/uvm/uvm_swap.c Wed Mar 14 20:48:13 2018
@@ -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 @@ void swapsys_unlock(void)
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 @@ sys_swapctl(struct lwp *l, const struct
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 @@ sys_swapctl(struct lwp *l, const struct
return 0;
}
- misc = SCARG(uap, misc);
userpath = kmem_alloc(SWAP_PATH_MAX, KM_SLEEP);
/*
@@ -494,51 +571,25 @@ sys_swapctl(struct lwp *l, const struct
* 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
-#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
+ case SWAP_STATS13:
#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;
- }
- if (SCARG(uap, cmd) == SWAP_GETDUMPDEV) {
- dev_t *devp = (dev_t *)SCARG(uap, arg);
-
- error = copyout(&dumpdev, devp, sizeof(dumpdev));
+
+ case SWAP_GETDUMPDEV:
+ error = copyout(&dumpdev, SCARG(uap, arg), sizeof(dumpdev));
goto out;
+ default:
+ break;
}
/*
@@ -744,12 +795,30 @@ out:
* is not known at build time. Hence it would not be possible to
* ensure it would fit in the stackgap in any case.
*/
-void
-uvm_swap_stats(int cmd, struct swapent *sep, int sec, register_t *retval)
+int
+uvm_swap_stats(char *ptr, int misc,
+ void (*f)(void *, const struct swapent *), size_t len,
+ register_t *retval)
{
struct swappri *spp;
struct swapdev *sdp;
+ struct swapent sep;
int count = 0;
+ int error;
+
+ KASSERT(len <= sizeof(sep));
+ if (len == 0)
+ return ENOSYS;
+
+ if (misc < 0)
+ return EINVAL;
+
+ if (misc == 0 || uvmexp.nswapdev == 0)
+ return 0;
+
+ /* Make sure userland cannot exhaust kernel memory */
+ if ((size_t)misc > (size_t)uvmexp.nswapdev)
+ misc = uvmexp.nswapdev;
KASSERT(rw_lock_held(&swap_syscall_lock));
@@ -757,64 +826,23 @@ uvm_swap_stats(int cmd, struct swapent *
TAILQ_FOREACH(sdp, &spp->spi_swapdev, swd_next) {
int inuse;
- if (sec-- <= 0)
+ if (misc-- <= 0)
break;
- /*
- * backwards compatibility for system call.
- * For NetBSD 1.3 and 5.0, we have to use
- * the 32 bit dev_t. For 5.0 and -current
- * we have to add the path.
- */
inuse = btodb((uint64_t)sdp->swd_npginuse <<
PAGE_SHIFT);
-#if defined(COMPAT_13) || defined(COMPAT_50)
- if (cmd == SWAP_STATS) {
-#endif
- sep->se_dev = sdp->swd_dev;
- sep->se_flags = sdp->swd_flags;
- sep->se_nblks = sdp->swd_nblks;
- sep->se_inuse = inuse;
- sep->se_priority = sdp->swd_priority;
- KASSERT(sdp->swd_pathlen <
- sizeof(sep->se_path));
- strcpy(sep->se_path, sdp->swd_path);
- sep++;
-#if defined(COMPAT_13)
- } else if (cmd == SWAP_STATS13) {
- struct swapent13 *sep13 =
- (struct swapent13 *)sep;
-
- sep13->se13_dev = sdp->swd_dev;
- sep13->se13_flags = sdp->swd_flags;
- sep13->se13_nblks = sdp->swd_nblks;
- sep13->se13_inuse = inuse;
- sep13->se13_priority = sdp->swd_priority;
- sep = (struct swapent *)(sep13 + 1);
-#endif
-#if defined(COMPAT_50)
- } else if (cmd == SWAP_STATS50) {
- struct swapent50 *sep50 =
- (struct swapent50 *)sep;
-
- sep50->se50_dev = sdp->swd_dev;
- sep50->se50_flags = sdp->swd_flags;
- sep50->se50_nblks = sdp->swd_nblks;
- sep50->se50_inuse = inuse;
- sep50->se50_priority = sdp->swd_priority;
- KASSERT(sdp->swd_pathlen <
- sizeof(sep50->se50_path));
- strcpy(sep50->se50_path, sdp->swd_path);
- sep = (struct swapent *)(sep50 + 1);
-#endif
-#if defined(COMPAT_13) || defined(COMPAT_50)
- }
-#endif
+ swapent_cvt(&sep, sdp, inuse);
+ if (f)
+ (*f)(&sep, &sep);
+ if ((error = copyout(&sep, ptr, len)) != 0)
+ return error;
+ ptr += len;
count++;
}
}
*retval = count;
+ return 0;
}
/*
Index: src/sys/uvm/uvm_swap.h
diff -u src/sys/uvm/uvm_swap.h:1.22 src/sys/uvm/uvm_swap.h:1.23
--- src/sys/uvm/uvm_swap.h:1.22 Thu Jul 30 06:25:49 2015
+++ src/sys/uvm/uvm_swap.h Wed Mar 14 20:48:13 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_swap.h,v 1.22 2015/07/30 10:25:49 christos Exp $ */
+/* $NetBSD: uvm_swap.h,v 1.23 2018/03/15 00:48:13 christos Exp $ */
/*
* Copyright (c) 1997 Matthew R. Green
@@ -38,10 +38,12 @@
#include "opt_vmswap.h"
#endif
-struct swapent;
struct lwp;
#if defined(VMSWAP)
+
+struct swapent;
+
int uvm_swap_get(struct vm_page *, int, int);
int uvm_swap_put(int, struct vm_page **, int, int);
int uvm_swap_alloc(int *, bool);
@@ -50,12 +52,14 @@ void uvm_swap_markbad(int, int);
bool uvm_swapisfull(void);
void swapsys_lock(krw_t);
void swapsys_unlock(void);
-void uvm_swap_stats(int, struct swapent *, int, register_t *);
+int uvm_swap_stats(char *, int,
+ void (*)(void *, const struct swapent *), size_t, register_t *);
#else /* defined(VMSWAP) */
#define uvm_swapisfull() true
#define uvm_swap_stats(c, sep, count, retval) { *retval = 0; }
#endif /* defined(VMSWAP) */
+
void uvm_swap_shutdown(struct lwp *);
#endif /* _KERNEL || _MODULE */