1 /* $NetBSD: irix_swap.c,v 1.21 2008/04/28 20:23:42 martin Exp $ */
2
3 /*-
4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Emmanuel Dreyfus.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: irix_swap.c,v 1.21 2008/04/28 20:23:42 martin Exp $");
34
35 #include <sys/types.h>
36 #include <sys/signal.h>
37 #include <sys/param.h>
38 #include <sys/mount.h>
39 #include <sys/malloc.h>
40 #include <sys/proc.h>
41 #include <sys/systm.h>
42 #include <sys/swap.h>
43 #include <sys/vnode.h>
44 #include <sys/namei.h>
45 #include <sys/syscallargs.h>
46
47 #include <uvm/uvm_page.h>
48 #include <uvm/uvm_swap.h>
49
50 #include <compat/common/compat_util.h>
51
52 #include <compat/irix/irix_types.h>
53 #include <compat/irix/irix_signal.h>
54 #include <compat/irix/irix_swap.h>
55 #include <compat/irix/irix_syscall.h>
56 #include <compat/irix/irix_syscallargs.h>
57
58 int
59 irix_sys_swapctl(struct lwp *l, const struct irix_sys_swapctl_args *uap, register_t *retval)
60 {
61 /* {
62 syscallarg(int) cmd;
63 syscallarg(void *) arg;
64 } */
65 struct sys_swapctl_args cup;
66 int error = 0;
67
68 #ifdef DEBUG_IRIX
69 printf("irix_sys_swapctl(): cmd = %d, arg = %p\n", SCARG(uap, cmd),
70 SCARG(uap, arg));
71 #endif
72
73 switch (SCARG(uap, cmd)) {
74 case IRIX_SC_ADD: /* Add a swap resource */
75 case IRIX_SC_SGIADD: /* Add a swap resource */
76 case IRIX_SC_REMOVE: {/* Remove a swap resource */
77 struct irix_xswapres isr;
78 size_t len = (SCARG(uap, cmd) == IRIX_SC_SGIADD) ?
79 sizeof(struct irix_xswapres) : sizeof(struct irix_swapres);
80
81 if ((error = copyin(SCARG(uap, arg), &isr, len)) != 0)
82 return error;
83 #ifdef DEBUG_IRIX
84 printf("irix_sys_swapctl(): sr_start=%d, sr_length=%d",
85 isr.sr_start, isr.sr_length);
86 if (SCARG(uap, cmd) == IRIX_SC_SGIADD)
87 printf(", sr_maxlength=%d, sr_vlength=%d",
88 isr.sr_maxlength, isr.sr_vlength);
89 printf("\n");
90 #endif
91 if (isr.sr_start != 0) {
92 printf("Warning: irix_sys_swapctl(): ");
93 printf("unsupported non null sr_start\n");
94 return EINVAL;
95 }
96 SCARG(&cup, cmd) =
97 (SCARG(uap, cmd) == IRIX_SC_REMOVE) ? SWAP_OFF : SWAP_ON;
98 SCARG(&cup, arg) = isr.sr_name;
99 SCARG(&cup, misc) =
100 (SCARG(uap, cmd) == IRIX_SC_SGIADD) ? isr.sr_pri : 0;
101 return sys_swapctl(l, &cup, retval);
102 break;
103 }
104
105
106 case IRIX_SC_GETNSWP: /* Get number of swap items */
107 SCARG(&cup, cmd) = SWAP_NSWAP;
108 SCARG(&cup, arg) = NULL;
109 SCARG(&cup, misc) = 0;
110 return sys_swapctl(l, &cup, retval);
111 break;
112
113 case IRIX_SC_LIST: { /* Get swap list */
114 struct irix_swaptable ist;
115 struct swapent *bse;
116 struct irix_swapent *ise, *uise;
117 int len, ilen, pathlen;
118 int i;
119 size_t blksz = dbtob(1); /* One swap block size in bytes */
120 int scale = (PAGE_SIZE / blksz);
121
122 if ((error = copyin(SCARG(uap, arg), &ist, sizeof(ist))) != 0)
123 return error;
124
125 uise = (struct irix_swapent *)((char *)SCARG(uap, arg) +
126 sizeof(ist.swt_n));
127
128 len = sizeof(struct swapent) * ist.swt_n;
129 bse = (struct swapent *)malloc(len, M_TEMP, M_WAITOK);
130
131 ilen = sizeof(struct irix_swapent) * ist.swt_n;
132 ise = (struct irix_swapent *)malloc(ilen, M_TEMP, M_WAITOK);
133
134 if ((error = copyin(uise, ise, ilen)) != 0)
135 return error;
136
137 uvm_swap_stats(SWAP_STATS, bse, ist.swt_n, retval);
138
139 for (i = 0; i < ist.swt_n; i++) {
140
141 pathlen = MIN(strlen(bse[i].se_path), IRIX_PATH_MAX);
142 if (ise[i].ste_path != NULL &&
143 ((error = copyout(&(bse[i].se_path),
144 ise[i].ste_path, pathlen)) != 0))
145 goto bad;
146
147 ise[i].ste_start = 0;
148 ise[i].ste_length = bse[i].se_nblks * blksz;
149 ise[i].ste_pages = bse[i].se_nblks / scale;
150 ise[i].ste_free = (bse[i].se_nblks - bse[i].se_inuse) /
151 scale;
152
153 ise[i].ste_flags = 0;
154 if (bse[i].se_flags & SWF_FAKE)
155 ise[i].ste_flags |= IRIX_ST_NOTREADY;
156
157 ise[i].ste_vpages = bse[i].se_inuse / scale;
158 ise[i].ste_maxpages = bse[i].se_nblks / scale;
159 ise[i].ste_lswap = 1; /* XXX */
160 ise[i].ste_pri = bse[i].se_priority;
161
162 }
163
164 error = copyout(ise, uise, ilen);
165 bad:
166 free(bse, M_TEMP);
167 free(ise, M_TEMP);
168 return error;
169 break;
170 }
171
172 case IRIX_SC_GETFREESWAP:
173 case IRIX_SC_GETSWAPVIRT: {
174 int entries;
175 struct swapent *sep;
176 int i, dontcare, sum = 0;
177
178 SCARG(&cup, cmd) = SWAP_NSWAP;
179 SCARG(&cup, arg) = NULL;
180 SCARG(&cup, misc) = 0;
181 if ((error = sys_swapctl(l, &cup,
182 (register_t *)(void *)&entries)) != 0)
183 return error;
184
185 sep = (struct swapent *)malloc(
186 sizeof(struct swapent) * entries, M_TEMP, M_WAITOK);
187 uvm_swap_stats(SWAP_STATS, sep, entries,
188 (register_t *)(void *)&dontcare);
189
190 if (SCARG(uap, cmd) == IRIX_SC_GETFREESWAP)
191 for (i = 0; i < entries; i++)
192 sum += (sep[i].se_nblks - sep[i].se_inuse);
193
194 if (SCARG(uap, cmd) == IRIX_SC_GETSWAPVIRT)
195 for (i = 0; i < entries; i++)
196 sum += sep[i].se_nblks;
197
198 /* dbtob(1) is the size in byte of one swap block */
199 sum = sum * IRIX_SWAP_BLKSZ / dbtob(1);
200
201 if ((error = copyout(&sum, SCARG(uap, arg), sizeof(sum))) != 0)
202 return error;
203 break;
204 }
205 default:
206 printf("irix_sys_swapctl(): unsupported command %d\n",
207 SCARG(uap, cmd));
208 return EINVAL;
209 break;
210 }
211 return 0;
212 }
213
Cache object: 0b18a8aeb24037d46a03c2e6eeda739d
|