Sun Jan 29 07:19:48 2012 UTC ()
Some further tidying for the COMPAT_50 quotactl code. Mostly cosmetic,
but also use PNBUF_GET() and PNBUF_PUT() for a path buffer instead of
malloc with M_TEMP.


(dholland)
diff -r1.14 -r1.15 src/sys/compat/common/vfs_syscalls_50.c

cvs diff -r1.14 -r1.15 src/sys/compat/common/vfs_syscalls_50.c (switch to unified diff)

--- src/sys/compat/common/vfs_syscalls_50.c 2012/01/29 07:19:04 1.14
+++ src/sys/compat/common/vfs_syscalls_50.c 2012/01/29 07:19:48 1.15
@@ -1,443 +1,443 @@ @@ -1,443 +1,443 @@
1/* $NetBSD: vfs_syscalls_50.c,v 1.14 2012/01/29 07:19:04 dholland Exp $ */ 1/* $NetBSD: vfs_syscalls_50.c,v 1.15 2012/01/29 07:19:48 dholland Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas. 8 * by Christos Zoulas.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software 18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement: 19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD 20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors. 21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its 22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived 23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission. 24 * from this software without specific prior written permission.
25 * 25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE. 36 * POSSIBILITY OF SUCH DAMAGE.
37 */ 37 */
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls_50.c,v 1.14 2012/01/29 07:19:04 dholland Exp $"); 39__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls_50.c,v 1.15 2012/01/29 07:19:48 dholland Exp $");
40 40
41#include <sys/param.h> 41#include <sys/param.h>
42#include <sys/systm.h> 42#include <sys/systm.h>
43#include <sys/namei.h> 43#include <sys/namei.h>
44#include <sys/filedesc.h> 44#include <sys/filedesc.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/file.h> 46#include <sys/file.h>
47#include <sys/stat.h> 47#include <sys/stat.h>
48#include <sys/socketvar.h> 48#include <sys/socketvar.h>
49#include <sys/vnode.h> 49#include <sys/vnode.h>
50#include <sys/mount.h> 50#include <sys/mount.h>
51#include <sys/proc.h> 51#include <sys/proc.h>
52#include <sys/uio.h> 52#include <sys/uio.h>
53#include <sys/dirent.h> 53#include <sys/dirent.h>
54#include <sys/malloc.h> 
55#include <sys/kauth.h> 54#include <sys/kauth.h>
56#include <sys/time.h> 55#include <sys/time.h>
57#include <sys/vfs_syscalls.h> 56#include <sys/vfs_syscalls.h>
58#ifndef LFS 57#ifndef LFS
59#define LFS 58#define LFS
60#endif 59#endif
61#include <sys/syscallargs.h> 60#include <sys/syscallargs.h>
62 61
63#include <ufs/lfs/lfs_extern.h> 62#include <ufs/lfs/lfs_extern.h>
64 63
65#include <sys/quota.h> 64#include <sys/quota.h>
66#include <sys/quotactl.h> 65#include <sys/quotactl.h>
67#include <ufs/ufs/quota1.h> 66#include <ufs/ufs/quota1.h>
68 67
69#include <compat/common/compat_util.h> 68#include <compat/common/compat_util.h>
70#include <compat/sys/time.h> 69#include <compat/sys/time.h>
71#include <compat/sys/stat.h> 70#include <compat/sys/stat.h>
72#include <compat/sys/dirent.h> 71#include <compat/sys/dirent.h>
73#include <compat/sys/mount.h> 72#include <compat/sys/mount.h>
74 73
75static void cvtstat(struct stat30 *, const struct stat *); 74static void cvtstat(struct stat30 *, const struct stat *);
76 75
77/* 76/*
78 * Convert from a new to an old stat structure. 77 * Convert from a new to an old stat structure.
79 */ 78 */
80static void 79static void
81cvtstat(struct stat30 *ost, const struct stat *st) 80cvtstat(struct stat30 *ost, const struct stat *st)
82{ 81{
83 82
84 ost->st_dev = st->st_dev; 83 ost->st_dev = st->st_dev;
85 ost->st_ino = st->st_ino; 84 ost->st_ino = st->st_ino;
86 ost->st_mode = st->st_mode; 85 ost->st_mode = st->st_mode;
87 ost->st_nlink = st->st_nlink; 86 ost->st_nlink = st->st_nlink;
88 ost->st_uid = st->st_uid; 87 ost->st_uid = st->st_uid;
89 ost->st_gid = st->st_gid; 88 ost->st_gid = st->st_gid;
90 ost->st_rdev = st->st_rdev; 89 ost->st_rdev = st->st_rdev;
91 timespec_to_timespec50(&st->st_atimespec, &ost->st_atimespec); 90 timespec_to_timespec50(&st->st_atimespec, &ost->st_atimespec);
92 timespec_to_timespec50(&st->st_mtimespec, &ost->st_mtimespec); 91 timespec_to_timespec50(&st->st_mtimespec, &ost->st_mtimespec);
93 timespec_to_timespec50(&st->st_ctimespec, &ost->st_ctimespec); 92 timespec_to_timespec50(&st->st_ctimespec, &ost->st_ctimespec);
94 timespec_to_timespec50(&st->st_birthtimespec, &ost->st_birthtimespec); 93 timespec_to_timespec50(&st->st_birthtimespec, &ost->st_birthtimespec);
95 ost->st_size = st->st_size; 94 ost->st_size = st->st_size;
96 ost->st_blocks = st->st_blocks; 95 ost->st_blocks = st->st_blocks;
97 ost->st_blksize = st->st_blksize; 96 ost->st_blksize = st->st_blksize;
98 ost->st_flags = st->st_flags; 97 ost->st_flags = st->st_flags;
99 ost->st_gen = st->st_gen; 98 ost->st_gen = st->st_gen;
100 memset(ost->st_spare, 0, sizeof(ost->st_spare)); 99 memset(ost->st_spare, 0, sizeof(ost->st_spare));
101} 100}
102 101
103/* 102/*
104 * Get file status; this version follows links. 103 * Get file status; this version follows links.
105 */ 104 */
106/* ARGSUSED */ 105/* ARGSUSED */
107int 106int
108compat_50_sys___stat30(struct lwp *l, const struct compat_50_sys___stat30_args *uap, register_t *retval) 107compat_50_sys___stat30(struct lwp *l, const struct compat_50_sys___stat30_args *uap, register_t *retval)
109{ 108{
110 /* { 109 /* {
111 syscallarg(const char *) path; 110 syscallarg(const char *) path;
112 syscallarg(struct stat30 *) ub; 111 syscallarg(struct stat30 *) ub;
113 } */ 112 } */
114 struct stat sb; 113 struct stat sb;
115 struct stat30 osb; 114 struct stat30 osb;
116 int error; 115 int error;
117 116
118 error = do_sys_stat(SCARG(uap, path), FOLLOW, &sb); 117 error = do_sys_stat(SCARG(uap, path), FOLLOW, &sb);
119 if (error) 118 if (error)
120 return error; 119 return error;
121 cvtstat(&osb, &sb); 120 cvtstat(&osb, &sb);
122 error = copyout(&osb, SCARG(uap, ub), sizeof (osb)); 121 error = copyout(&osb, SCARG(uap, ub), sizeof (osb));
123 return error; 122 return error;
124} 123}
125 124
126 125
127/* 126/*
128 * Get file status; this version does not follow links. 127 * Get file status; this version does not follow links.
129 */ 128 */
130/* ARGSUSED */ 129/* ARGSUSED */
131int 130int
132compat_50_sys___lstat30(struct lwp *l, const struct compat_50_sys___lstat30_args *uap, register_t *retval) 131compat_50_sys___lstat30(struct lwp *l, const struct compat_50_sys___lstat30_args *uap, register_t *retval)
133{ 132{
134 /* { 133 /* {
135 syscallarg(const char *) path; 134 syscallarg(const char *) path;
136 syscallarg(struct stat30 *) ub; 135 syscallarg(struct stat30 *) ub;
137 } */ 136 } */
138 struct stat sb; 137 struct stat sb;
139 struct stat30 osb; 138 struct stat30 osb;
140 int error; 139 int error;
141 140
142 error = do_sys_stat(SCARG(uap, path), NOFOLLOW, &sb); 141 error = do_sys_stat(SCARG(uap, path), NOFOLLOW, &sb);
143 if (error) 142 if (error)
144 return error; 143 return error;
145 cvtstat(&osb, &sb); 144 cvtstat(&osb, &sb);
146 error = copyout(&osb, SCARG(uap, ub), sizeof (osb)); 145 error = copyout(&osb, SCARG(uap, ub), sizeof (osb));
147 return error; 146 return error;
148} 147}
149 148
150/* 149/*
151 * Return status information about a file descriptor. 150 * Return status information about a file descriptor.
152 */ 151 */
153/* ARGSUSED */ 152/* ARGSUSED */
154int 153int
155compat_50_sys___fstat30(struct lwp *l, const struct compat_50_sys___fstat30_args *uap, register_t *retval) 154compat_50_sys___fstat30(struct lwp *l, const struct compat_50_sys___fstat30_args *uap, register_t *retval)
156{ 155{
157 /* { 156 /* {
158 syscallarg(int) fd; 157 syscallarg(int) fd;
159 syscallarg(struct stat30 *) sb; 158 syscallarg(struct stat30 *) sb;
160 } */ 159 } */
161 struct stat sb; 160 struct stat sb;
162 struct stat30 osb; 161 struct stat30 osb;
163 int error; 162 int error;
164 163
165 error = do_sys_fstat(SCARG(uap, fd), &sb); 164 error = do_sys_fstat(SCARG(uap, fd), &sb);
166 if (error) 165 if (error)
167 return error; 166 return error;
168 cvtstat(&osb, &sb); 167 cvtstat(&osb, &sb);
169 error = copyout(&osb, SCARG(uap, sb), sizeof (osb)); 168 error = copyout(&osb, SCARG(uap, sb), sizeof (osb));
170 return error; 169 return error;
171} 170}
172 171
173/* ARGSUSED */ 172/* ARGSUSED */
174int 173int
175compat_50_sys___fhstat40(struct lwp *l, const struct compat_50_sys___fhstat40_args *uap, register_t *retval) 174compat_50_sys___fhstat40(struct lwp *l, const struct compat_50_sys___fhstat40_args *uap, register_t *retval)
176{ 175{
177 /* { 176 /* {
178 syscallarg(const void *) fhp; 177 syscallarg(const void *) fhp;
179 syscallarg(size_t) fh_size; 178 syscallarg(size_t) fh_size;
180 syscallarg(struct stat30 *) sb; 179 syscallarg(struct stat30 *) sb;
181 } */ 180 } */
182 struct stat sb; 181 struct stat sb;
183 struct stat30 osb; 182 struct stat30 osb;
184 int error; 183 int error;
185 184
186 error = do_fhstat(l, SCARG(uap, fhp), SCARG(uap, fh_size), &sb); 185 error = do_fhstat(l, SCARG(uap, fhp), SCARG(uap, fh_size), &sb);
187 if (error) 186 if (error)
188 return error; 187 return error;
189 cvtstat(&osb, &sb); 188 cvtstat(&osb, &sb);
190 error = copyout(&osb, SCARG(uap, sb), sizeof (osb)); 189 error = copyout(&osb, SCARG(uap, sb), sizeof (osb));
191 return error; 190 return error;
192} 191}
193 192
194static int 193static int
195compat_50_do_sys_utimes(struct lwp *l, struct vnode *vp, const char *path, 194compat_50_do_sys_utimes(struct lwp *l, struct vnode *vp, const char *path,
196 int flag, const struct timeval50 *tptr) 195 int flag, const struct timeval50 *tptr)
197{ 196{
198 struct timeval tv[2], *tvp; 197 struct timeval tv[2], *tvp;
199 struct timeval50 tv50[2]; 198 struct timeval50 tv50[2];
200 if (tptr) { 199 if (tptr) {
201 int error = copyin(tptr, tv50, sizeof(tv50)); 200 int error = copyin(tptr, tv50, sizeof(tv50));
202 if (error) 201 if (error)
203 return error; 202 return error;
204 timeval50_to_timeval(&tv50[0], &tv[0]); 203 timeval50_to_timeval(&tv50[0], &tv[0]);
205 timeval50_to_timeval(&tv50[1], &tv[1]); 204 timeval50_to_timeval(&tv50[1], &tv[1]);
206 tvp = tv; 205 tvp = tv;
207 } else 206 } else
208 tvp = NULL; 207 tvp = NULL;
209 return do_sys_utimes(l, vp, path, flag, tvp, UIO_SYSSPACE); 208 return do_sys_utimes(l, vp, path, flag, tvp, UIO_SYSSPACE);
210} 209}
211  210
212/* 211/*
213 * Set the access and modification times given a path name; this 212 * Set the access and modification times given a path name; this
214 * version follows links. 213 * version follows links.
215 */ 214 */
216/* ARGSUSED */ 215/* ARGSUSED */
217int 216int
218compat_50_sys_utimes(struct lwp *l, const struct compat_50_sys_utimes_args *uap, 217compat_50_sys_utimes(struct lwp *l, const struct compat_50_sys_utimes_args *uap,
219 register_t *retval) 218 register_t *retval)
220{ 219{
221 /* { 220 /* {
222 syscallarg(const char *) path; 221 syscallarg(const char *) path;
223 syscallarg(const struct timeval50 *) tptr; 222 syscallarg(const struct timeval50 *) tptr;
224 } */ 223 } */
225 224
226 return compat_50_do_sys_utimes(l, NULL, SCARG(uap, path), FOLLOW, 225 return compat_50_do_sys_utimes(l, NULL, SCARG(uap, path), FOLLOW,
227 SCARG(uap, tptr)); 226 SCARG(uap, tptr));
228} 227}
229 228
230/* 229/*
231 * Set the access and modification times given a file descriptor. 230 * Set the access and modification times given a file descriptor.
232 */ 231 */
233/* ARGSUSED */ 232/* ARGSUSED */
234int 233int
235compat_50_sys_futimes(struct lwp *l, 234compat_50_sys_futimes(struct lwp *l,
236 const struct compat_50_sys_futimes_args *uap, register_t *retval) 235 const struct compat_50_sys_futimes_args *uap, register_t *retval)
237{ 236{
238 /* { 237 /* {
239 syscallarg(int) fd; 238 syscallarg(int) fd;
240 syscallarg(const struct timeval50 *) tptr; 239 syscallarg(const struct timeval50 *) tptr;
241 } */ 240 } */
242 int error; 241 int error;
243 struct file *fp; 242 struct file *fp;
244 243
245 /* fd_getvnode() will use the descriptor for us */ 244 /* fd_getvnode() will use the descriptor for us */
246 if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0) 245 if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
247 return error; 246 return error;
248 error = compat_50_do_sys_utimes(l, fp->f_data, NULL, 0, 247 error = compat_50_do_sys_utimes(l, fp->f_data, NULL, 0,
249 SCARG(uap, tptr)); 248 SCARG(uap, tptr));
250 fd_putfile(SCARG(uap, fd)); 249 fd_putfile(SCARG(uap, fd));
251 return error; 250 return error;
252} 251}
253 252
254/* 253/*
255 * Set the access and modification times given a path name; this 254 * Set the access and modification times given a path name; this
256 * version does not follow links. 255 * version does not follow links.
257 */ 256 */
258int 257int
259compat_50_sys_lutimes(struct lwp *l, 258compat_50_sys_lutimes(struct lwp *l,
260 const struct compat_50_sys_lutimes_args *uap, register_t *retval) 259 const struct compat_50_sys_lutimes_args *uap, register_t *retval)
261{ 260{
262 /* { 261 /* {
263 syscallarg(const char *) path; 262 syscallarg(const char *) path;
264 syscallarg(const struct timeval50 *) tptr; 263 syscallarg(const struct timeval50 *) tptr;
265 } */ 264 } */
266 265
267 return compat_50_do_sys_utimes(l, NULL, SCARG(uap, path), NOFOLLOW, 266 return compat_50_do_sys_utimes(l, NULL, SCARG(uap, path), NOFOLLOW,
268 SCARG(uap, tptr)); 267 SCARG(uap, tptr));
269} 268}
270 269
271int 270int
272compat_50_sys_lfs_segwait(struct lwp *l, 271compat_50_sys_lfs_segwait(struct lwp *l,
273 const struct compat_50_sys_lfs_segwait_args *uap, register_t *retval) 272 const struct compat_50_sys_lfs_segwait_args *uap, register_t *retval)
274{ 273{
275 /* { 274 /* {
276 syscallarg(fsid_t *) fsidp; 275 syscallarg(fsid_t *) fsidp;
277 syscallarg(struct timeval50 *) tv; 276 syscallarg(struct timeval50 *) tv;
278 } */ 277 } */
279#ifdef notyet 278#ifdef notyet
280 struct timeval atv; 279 struct timeval atv;
281 struct timeval50 atv50; 280 struct timeval50 atv50;
282 fsid_t fsid; 281 fsid_t fsid;
283 int error; 282 int error;
284 283
285 /* XXX need we be su to segwait? */ 284 /* XXX need we be su to segwait? */
286 if ((error = kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, 285 if ((error = kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER,
287 NULL)) != 0) 286 NULL)) != 0)
288 return (error); 287 return (error);
289 if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0) 288 if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
290 return (error); 289 return (error);
291 290
292 if (SCARG(uap, tv)) { 291 if (SCARG(uap, tv)) {
293 error = copyin(SCARG(uap, tv), &atv50, sizeof(atv50)); 292 error = copyin(SCARG(uap, tv), &atv50, sizeof(atv50));
294 if (error) 293 if (error)
295 return (error); 294 return (error);
296 timeval50_to_timeval(&atv50, &atv); 295 timeval50_to_timeval(&atv50, &atv);
297 if (itimerfix(&atv)) 296 if (itimerfix(&atv))
298 return (EINVAL); 297 return (EINVAL);
299 } else /* NULL or invalid */ 298 } else /* NULL or invalid */
300 atv.tv_sec = atv.tv_usec = 0; 299 atv.tv_sec = atv.tv_usec = 0;
301 return lfs_segwait(&fsid, &atv); 300 return lfs_segwait(&fsid, &atv);
302#else 301#else
303 return ENOSYS; 302 return ENOSYS;
304#endif 303#endif
305} 304}
306 305
307int 306int
308compat_50_sys_mknod(struct lwp *l, 307compat_50_sys_mknod(struct lwp *l,
309 const struct compat_50_sys_mknod_args *uap, register_t *retval) 308 const struct compat_50_sys_mknod_args *uap, register_t *retval)
310{ 309{
311 /* { 310 /* {
312 syscallarg(const char *) path; 311 syscallarg(const char *) path;
313 syscallarg(mode_t) mode; 312 syscallarg(mode_t) mode;
314 syscallarg(uint32_t) dev; 313 syscallarg(uint32_t) dev;
315 } */ 314 } */
316 return do_sys_mknod(l, SCARG(uap, path), SCARG(uap, mode), 315 return do_sys_mknod(l, SCARG(uap, path), SCARG(uap, mode),
317 SCARG(uap, dev), retval, UIO_USERSPACE); 316 SCARG(uap, dev), retval, UIO_USERSPACE);
318} 317}
319 318
320/* ARGSUSED */ 319/* ARGSUSED */
321int  320int
322compat_50_sys_quotactl(struct lwp *l, const struct compat_50_sys_quotactl_args *uap, register_t *retval) 321compat_50_sys_quotactl(struct lwp *l, const struct compat_50_sys_quotactl_args *uap, register_t *retval)
323{ 322{
324 /* { 323 /* {
325 syscallarg(const char *) path; 324 syscallarg(const char *) path;
326 syscallarg(int) cmd; 325 syscallarg(int) cmd;
327 syscallarg(int) uid; 326 syscallarg(int) uid;
328 syscallarg(void *) arg;  327 syscallarg(void *) arg;
329 } */ 328 } */
330 struct mount *mp; 
331 int error; 
332 struct vnode *vp; 329 struct vnode *vp;
333 int q1cmd = SCARG(uap, cmd); 330 struct mount *mp;
334 char *bufpath; 331 int q1cmd;
 332 int idtype;
 333 char *qfile;
335 struct dqblk dqblk; 334 struct dqblk dqblk;
336 struct quotakey key; 335 struct quotakey key;
337 struct quotaval blocks, files; 336 struct quotaval blocks, files;
338 struct quotastat qstat; 337 struct quotastat qstat;
339 struct vfs_quotactl_args args; 338 struct vfs_quotactl_args args;
340 int idtype; 339 int error;
341 340
342 error = namei_simple_user(SCARG(uap, path), 341 error = namei_simple_user(SCARG(uap, path),
343 NSM_FOLLOW_TRYEMULROOT, &vp); 342 NSM_FOLLOW_TRYEMULROOT, &vp);
344 if (error != 0) 343 if (error != 0)
345 return (error);  344 return (error);
346 345
347 mp = vp->v_mount; 346 mp = vp->v_mount;
 347 q1cmd = SCARG(uap, cmd);
348 idtype = quota_idtype_from_ufs(q1cmd & SUBCMDMASK); 348 idtype = quota_idtype_from_ufs(q1cmd & SUBCMDMASK);
349 349
350 switch ((q1cmd & ~SUBCMDMASK) >> SUBCMDSHIFT) { 350 switch ((q1cmd & ~SUBCMDMASK) >> SUBCMDSHIFT) {
351 case Q_QUOTAON: 351 case Q_QUOTAON:
352 bufpath = malloc(PATH_MAX * sizeof(char), M_TEMP, M_WAITOK); 352 qfile = PNBUF_GET();
353 error = copyinstr(SCARG(uap, arg), bufpath, PATH_MAX, NULL); 353 error = copyinstr(SCARG(uap, arg), qfile, PATH_MAX, NULL);
354 if (error != 0) { 354 if (error != 0) {
355 free(bufpath, M_TEMP); 355 PNBUF_PUT(qfile);
356 break; 356 break;
357 } 357 }
358 358
359 args.qc_op = QUOTACTL_QUOTAON; 359 args.qc_op = QUOTACTL_QUOTAON;
360 args.u.quotaon.qc_quotafile = bufpath; 360 args.u.quotaon.qc_quotafile = qfile;
361 args.u.quotaon.qc_idtype = idtype; 361 args.u.quotaon.qc_idtype = idtype;
362 error = VFS_QUOTACTL(mp, &args); 362 error = VFS_QUOTACTL(mp, &args);
363 363
364 free(bufpath, M_TEMP); 364 PNBUF_PUT(qfile);
365 break; 365 break;
366 366
367 case Q_QUOTAOFF: 367 case Q_QUOTAOFF:
368 args.qc_op = QUOTACTL_QUOTAOFF; 368 args.qc_op = QUOTACTL_QUOTAOFF;
369 args.u.quotaoff.qc_idtype = idtype; 369 args.u.quotaoff.qc_idtype = idtype;
370 error = VFS_QUOTACTL(mp, &args); 370 error = VFS_QUOTACTL(mp, &args);
371 break; 371 break;
372 372
373 case Q_GETQUOTA: 373 case Q_GETQUOTA:
374 key.qk_idtype = idtype; 374 key.qk_idtype = idtype;
375 key.qk_id = SCARG(uap, uid); 375 key.qk_id = SCARG(uap, uid);
376 args.qc_op = QUOTACTL_GET; 376 args.qc_op = QUOTACTL_GET;
377 args.u.get.qc_key = &key; 377 args.u.get.qc_key = &key;
378 378
379 key.qk_objtype = QUOTA_OBJTYPE_BLOCKS; 379 key.qk_objtype = QUOTA_OBJTYPE_BLOCKS;
380 args.u.get.qc_ret = &blocks; 380 args.u.get.qc_ret = &blocks;
381 error = VFS_QUOTACTL(mp, &args); 381 error = VFS_QUOTACTL(mp, &args);
382 if (error) { 382 if (error) {
383 break; 383 break;
384 } 384 }
385 385
386 key.qk_objtype = QUOTA_OBJTYPE_FILES; 386 key.qk_objtype = QUOTA_OBJTYPE_FILES;
387 args.u.get.qc_ret = &files; 387 args.u.get.qc_ret = &files;
388 error = VFS_QUOTACTL(mp, &args); 388 error = VFS_QUOTACTL(mp, &args);
389 if (error) { 389 if (error) {
390 break; 390 break;
391 } 391 }
392 392
393 quotavals_to_dqblk(&blocks, &files, &dqblk); 393 quotavals_to_dqblk(&blocks, &files, &dqblk);
394 error = copyout(&dqblk, SCARG(uap, arg), sizeof(dqblk)); 394 error = copyout(&dqblk, SCARG(uap, arg), sizeof(dqblk));
395 break; 395 break;
396  396
397 case Q_SETQUOTA: 397 case Q_SETQUOTA:
398 error = copyin(SCARG(uap, arg), &dqblk, sizeof(dqblk)); 398 error = copyin(SCARG(uap, arg), &dqblk, sizeof(dqblk));
399 if (error) { 399 if (error) {
400 break; 400 break;
401 } 401 }
402 dqblk_to_quotavals(&dqblk, &blocks, &files); 402 dqblk_to_quotavals(&dqblk, &blocks, &files);
403 403
404 key.qk_idtype = idtype; 404 key.qk_idtype = idtype;
405 key.qk_id = SCARG(uap, uid); 405 key.qk_id = SCARG(uap, uid);
406 args.qc_op = QUOTACTL_PUT; 406 args.qc_op = QUOTACTL_PUT;
407 args.u.put.qc_key = &key; 407 args.u.put.qc_key = &key;
408 408
409 key.qk_objtype = QUOTA_OBJTYPE_BLOCKS; 409 key.qk_objtype = QUOTA_OBJTYPE_BLOCKS;
410 args.u.put.qc_val = &blocks; 410 args.u.put.qc_val = &blocks;
411 error = VFS_QUOTACTL(mp, &args); 411 error = VFS_QUOTACTL(mp, &args);
412 if (error) { 412 if (error) {
413 break; 413 break;
414 } 414 }
415 415
416 key.qk_objtype = QUOTA_OBJTYPE_FILES; 416 key.qk_objtype = QUOTA_OBJTYPE_FILES;
417 args.u.put.qc_val = &files; 417 args.u.put.qc_val = &files;
418 error = VFS_QUOTACTL(mp, &args); 418 error = VFS_QUOTACTL(mp, &args);
419 break; 419 break;
420  420
421 case Q_SYNC: 421 case Q_SYNC:
422 /* 422 /*
423 * not supported but used only to see if quota is supported, 423 * not supported but used only to see if quota is supported,
424 * emulate with stat 424 * emulate with stat
425 * 425 *
426 * XXX should probably be supported 426 * XXX should probably be supported
427 */ 427 */
428 (void)idtype; /* not used */ 428 (void)idtype; /* not used */
429 429
430 args.qc_op = QUOTACTL_STAT; 430 args.qc_op = QUOTACTL_STAT;
431 args.u.stat.qc_ret = &qstat; 431 args.u.stat.qc_ret = &qstat;
432 error = VFS_QUOTACTL(mp, &args); 432 error = VFS_QUOTACTL(mp, &args);
433 break; 433 break;
434 434
435 case Q_SETUSE: 435 case Q_SETUSE:
436 default: 436 default:
437 error = EOPNOTSUPP; 437 error = EOPNOTSUPP;
438 break; 438 break;
439 } 439 }
440 440
441 vrele(vp); 441 vrele(vp);
442 return error; 442 return error;
443} 443}