xref: /freebsd/sys/kern/vfs_extattr.c (revision a1a4f1a0d87b594d3f17a97dc0127eec1417e6f6)
1 /*
2  * Copyright (c) 1989, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  * (c) UNIX System Laboratories, Inc.
5  * All or some portions of this file are derived from material licensed
6  * to the University of California by American Telephone and Telegraph
7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8  * the permission of UNIX System Laboratories, Inc.
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  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *	This product includes software developed by the University of
21  *	California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  *	@(#)vfs_syscalls.c	8.13 (Berkeley) 4/15/94
39  * $FreeBSD$
40  */
41 
42 /* For 4.3 integer FS ID compatibility */
43 #include "opt_compat.h"
44 
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/buf.h>
48 #include <sys/sysent.h>
49 #include <sys/sysproto.h>
50 #include <sys/namei.h>
51 #include <sys/filedesc.h>
52 #include <sys/kernel.h>
53 #include <sys/fcntl.h>
54 #include <sys/file.h>
55 #include <sys/linker.h>
56 #include <sys/stat.h>
57 #include <sys/unistd.h>
58 #include <sys/vnode.h>
59 #include <sys/malloc.h>
60 #include <sys/mount.h>
61 #include <sys/proc.h>
62 #include <sys/dirent.h>
63 
64 #include <miscfs/union/union.h>
65 
66 #include <vm/vm.h>
67 #include <vm/vm_object.h>
68 #include <vm/vm_extern.h>
69 #include <vm/vm_zone.h>
70 #include <sys/sysctl.h>
71 
72 static int change_dir __P((struct nameidata *ndp, struct proc *p));
73 static void checkdirs __P((struct vnode *olddp));
74 static int chroot_refuse_vdir_fds __P((struct filedesc *fdp));
75 static int getutimes __P((const struct timeval *, struct timespec *));
76 static int setfown __P((struct proc *, struct vnode *, uid_t, gid_t));
77 static int setfmode __P((struct proc *, struct vnode *, int));
78 static int setfflags __P((struct proc *, struct vnode *, int));
79 static int setutimes __P((struct proc *, struct vnode *,
80     const struct timespec *, int));
81 static int	usermount = 0;	/* if 1, non-root can mount fs. */
82 
83 int (*union_dircheckp) __P((struct proc *, struct vnode **, struct file *));
84 
85 SYSCTL_INT(_vfs, OID_AUTO, usermount, CTLFLAG_RW, &usermount, 0, "");
86 
87 /*
88  * Virtual File System System Calls
89  */
90 
91 /*
92  * Mount a file system.
93  */
94 #ifndef _SYS_SYSPROTO_H_
95 struct mount_args {
96 	char	*type;
97 	char	*path;
98 	int	flags;
99 	caddr_t	data;
100 };
101 #endif
102 /* ARGSUSED */
103 int
104 mount(p, uap)
105 	struct proc *p;
106 	register struct mount_args /* {
107 		syscallarg(char *) type;
108 		syscallarg(char *) path;
109 		syscallarg(int) flags;
110 		syscallarg(caddr_t) data;
111 	} */ *uap;
112 {
113 	struct vnode *vp;
114 	struct mount *mp;
115 	struct vfsconf *vfsp;
116 	int error, flag = 0, flag2 = 0;
117 	struct vattr va;
118 #ifdef COMPAT_43
119 	u_long fstypenum;
120 #endif
121 	struct nameidata nd;
122 	char fstypename[MFSNAMELEN];
123 
124 	if (usermount == 0 && (error = suser(p)))
125 		return (error);
126 	/*
127 	 * Do not allow NFS export by non-root users.
128 	 */
129 	if (SCARG(uap, flags) & MNT_EXPORTED) {
130 		error = suser(p);
131 		if (error)
132 			return (error);
133 	}
134 	/*
135 	 * Silently enforce MNT_NOSUID and MNT_NODEV for non-root users
136 	 */
137 	if (suser_xxx(p->p_ucred, 0, 0))
138 		SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV;
139 	/*
140 	 * Get vnode to be covered
141 	 */
142 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
143 	    SCARG(uap, path), p);
144 	if ((error = namei(&nd)) != 0)
145 		return (error);
146 	vp = nd.ni_vp;
147 	if (SCARG(uap, flags) & MNT_UPDATE) {
148 		if ((vp->v_flag & VROOT) == 0) {
149 			vput(vp);
150 			return (EINVAL);
151 		}
152 		mp = vp->v_mount;
153 		flag = mp->mnt_flag;
154 		flag2 = mp->mnt_kern_flag;
155 		/*
156 		 * We only allow the filesystem to be reloaded if it
157 		 * is currently mounted read-only.
158 		 */
159 		if ((SCARG(uap, flags) & MNT_RELOAD) &&
160 		    ((mp->mnt_flag & MNT_RDONLY) == 0)) {
161 			vput(vp);
162 			return (EOPNOTSUPP);	/* Needs translation */
163 		}
164 		mp->mnt_flag |=
165 		    SCARG(uap, flags) & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE);
166 		/*
167 		 * Only root, or the user that did the original mount is
168 		 * permitted to update it.
169 		 */
170 		if (mp->mnt_stat.f_owner != p->p_ucred->cr_uid &&
171 		    (error = suser(p))) {
172 			vput(vp);
173 			return (error);
174 		}
175 		if (vfs_busy(mp, LK_NOWAIT, 0, p)) {
176 			vput(vp);
177 			return (EBUSY);
178 		}
179 		VOP_UNLOCK(vp, 0, p);
180 		goto update;
181 	}
182 	/*
183 	 * If the user is not root, ensure that they own the directory
184 	 * onto which we are attempting to mount.
185 	 */
186 	if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)) ||
187 	    (va.va_uid != p->p_ucred->cr_uid &&
188 	     (error = suser(p)))) {
189 		vput(vp);
190 		return (error);
191 	}
192 	if ((error = vinvalbuf(vp, V_SAVE, p->p_ucred, p, 0, 0)) != 0)
193 		return (error);
194 	if (vp->v_type != VDIR) {
195 		vput(vp);
196 		return (ENOTDIR);
197 	}
198 #ifdef COMPAT_43
199 	/*
200 	 * Historically filesystem types were identified by number. If we
201 	 * get an integer for the filesystem type instead of a string, we
202 	 * check to see if it matches one of the historic filesystem types.
203 	 */
204 	fstypenum = (uintptr_t)SCARG(uap, type);
205 	if (fstypenum < maxvfsconf) {
206 		for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
207 			if (vfsp->vfc_typenum == fstypenum)
208 				break;
209 		if (vfsp == NULL) {
210 			vput(vp);
211 			return (ENODEV);
212 		}
213 		strncpy(fstypename, vfsp->vfc_name, MFSNAMELEN);
214 	} else
215 #endif /* COMPAT_43 */
216 	if ((error = copyinstr(SCARG(uap, type), fstypename, MFSNAMELEN, NULL)) != 0) {
217 		vput(vp);
218 		return (error);
219 	}
220 	for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
221 		if (!strcmp(vfsp->vfc_name, fstypename))
222 			break;
223 	if (vfsp == NULL) {
224 		linker_file_t lf;
225 
226 		/* Refuse to load modules if securelevel raised */
227 		if (securelevel > 0) {
228 			vput(vp);
229 			return EPERM;
230 		}
231 		/* Only load modules for root (very important!) */
232 		if ((error = suser(p)) != 0) {
233 			vput(vp);
234 			return error;
235 		}
236 		error = linker_load_file(fstypename, &lf);
237 		if (error || lf == NULL) {
238 			vput(vp);
239 			if (lf == NULL)
240 				error = ENODEV;
241 			return error;
242 		}
243 		lf->userrefs++;
244 		/* lookup again, see if the VFS was loaded */
245 		for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
246 			if (!strcmp(vfsp->vfc_name, fstypename))
247 				break;
248 		if (vfsp == NULL) {
249 			lf->userrefs--;
250 			linker_file_unload(lf);
251 			vput(vp);
252 			return (ENODEV);
253 		}
254 	}
255 	simple_lock(&vp->v_interlock);
256 	if ((vp->v_flag & VMOUNT) != 0 ||
257 	    vp->v_mountedhere != NULL) {
258 		simple_unlock(&vp->v_interlock);
259 		vput(vp);
260 		return (EBUSY);
261 	}
262 	vp->v_flag |= VMOUNT;
263 	simple_unlock(&vp->v_interlock);
264 
265 	/*
266 	 * Allocate and initialize the filesystem.
267 	 */
268 	mp = (struct mount *)malloc((u_long)sizeof(struct mount),
269 		M_MOUNT, M_WAITOK);
270 	bzero((char *)mp, (u_long)sizeof(struct mount));
271 	lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, LK_NOPAUSE);
272 	(void)vfs_busy(mp, LK_NOWAIT, 0, p);
273 	mp->mnt_op = vfsp->vfc_vfsops;
274 	mp->mnt_vfc = vfsp;
275 	vfsp->vfc_refcount++;
276 	mp->mnt_stat.f_type = vfsp->vfc_typenum;
277 	mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
278 	strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
279 	mp->mnt_vnodecovered = vp;
280 	mp->mnt_stat.f_owner = p->p_ucred->cr_uid;
281 	VOP_UNLOCK(vp, 0, p);
282 update:
283 	/*
284 	 * Set the mount level flags.
285 	 */
286 	if (SCARG(uap, flags) & MNT_RDONLY)
287 		mp->mnt_flag |= MNT_RDONLY;
288 	else if (mp->mnt_flag & MNT_RDONLY)
289 		mp->mnt_kern_flag |= MNTK_WANTRDWR;
290 	mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
291 	    MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_NOATIME |
292 	    MNT_NOSYMFOLLOW |
293 	    MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR);
294 	mp->mnt_flag |= SCARG(uap, flags) & (MNT_NOSUID | MNT_NOEXEC |
295 	    MNT_NODEV | MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC | MNT_FORCE |
296 	    MNT_NOSYMFOLLOW |
297 	    MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR);
298 	/*
299 	 * Mount the filesystem.
300 	 */
301 	error = VFS_MOUNT(mp, SCARG(uap, path), SCARG(uap, data), &nd, p);
302 	if (mp->mnt_flag & MNT_UPDATE) {
303 		vrele(vp);
304 		if (mp->mnt_kern_flag & MNTK_WANTRDWR)
305 			mp->mnt_flag &= ~MNT_RDONLY;
306 		mp->mnt_flag &=~ (MNT_UPDATE | MNT_RELOAD | MNT_FORCE);
307 		mp->mnt_kern_flag &=~ MNTK_WANTRDWR;
308 		if (error) {
309 			mp->mnt_flag = flag;
310 			mp->mnt_kern_flag = flag2;
311 		}
312 		if ((mp->mnt_flag & MNT_RDONLY) == 0) {
313 			if (mp->mnt_syncer == NULL)
314 				error = vfs_allocate_syncvnode(mp);
315 		} else {
316 			if (mp->mnt_syncer != NULL)
317 				vrele(mp->mnt_syncer);
318 			mp->mnt_syncer = NULL;
319 		}
320 		vfs_unbusy(mp, p);
321 		return (error);
322 	}
323 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
324 	/*
325 	 * Put the new filesystem on the mount list after root.
326 	 */
327 	cache_purge(vp);
328 	if (!error) {
329 		simple_lock(&vp->v_interlock);
330 		vp->v_flag &= ~VMOUNT;
331 		vp->v_mountedhere = mp;
332 		simple_unlock(&vp->v_interlock);
333 		simple_lock(&mountlist_slock);
334 		CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
335 		simple_unlock(&mountlist_slock);
336 		checkdirs(vp);
337 		VOP_UNLOCK(vp, 0, p);
338 		if ((mp->mnt_flag & MNT_RDONLY) == 0)
339 			error = vfs_allocate_syncvnode(mp);
340 		vfs_unbusy(mp, p);
341 		if ((error = VFS_START(mp, 0, p)) != 0)
342 			vrele(vp);
343 	} else {
344 		simple_lock(&vp->v_interlock);
345 		vp->v_flag &= ~VMOUNT;
346 		simple_unlock(&vp->v_interlock);
347 		mp->mnt_vfc->vfc_refcount--;
348 		vfs_unbusy(mp, p);
349 		free((caddr_t)mp, M_MOUNT);
350 		vput(vp);
351 	}
352 	return (error);
353 }
354 
355 /*
356  * Scan all active processes to see if any of them have a current
357  * or root directory onto which the new filesystem has just been
358  * mounted. If so, replace them with the new mount point.
359  */
360 static void
361 checkdirs(olddp)
362 	struct vnode *olddp;
363 {
364 	struct filedesc *fdp;
365 	struct vnode *newdp;
366 	struct proc *p;
367 
368 	if (olddp->v_usecount == 1)
369 		return;
370 	if (VFS_ROOT(olddp->v_mountedhere, &newdp))
371 		panic("mount: lost mount");
372 	for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
373 		fdp = p->p_fd;
374 		if (fdp->fd_cdir == olddp) {
375 			vrele(fdp->fd_cdir);
376 			VREF(newdp);
377 			fdp->fd_cdir = newdp;
378 		}
379 		if (fdp->fd_rdir == olddp) {
380 			vrele(fdp->fd_rdir);
381 			VREF(newdp);
382 			fdp->fd_rdir = newdp;
383 		}
384 	}
385 	if (rootvnode == olddp) {
386 		vrele(rootvnode);
387 		VREF(newdp);
388 		rootvnode = newdp;
389 	}
390 	vput(newdp);
391 }
392 
393 /*
394  * Unmount a file system.
395  *
396  * Note: unmount takes a path to the vnode mounted on as argument,
397  * not special file (as before).
398  */
399 #ifndef _SYS_SYSPROTO_H_
400 struct unmount_args {
401 	char	*path;
402 	int	flags;
403 };
404 #endif
405 /* ARGSUSED */
406 int
407 unmount(p, uap)
408 	struct proc *p;
409 	register struct unmount_args /* {
410 		syscallarg(char *) path;
411 		syscallarg(int) flags;
412 	} */ *uap;
413 {
414 	register struct vnode *vp;
415 	struct mount *mp;
416 	int error;
417 	struct nameidata nd;
418 
419 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
420 	    SCARG(uap, path), p);
421 	if ((error = namei(&nd)) != 0)
422 		return (error);
423 	vp = nd.ni_vp;
424 	mp = vp->v_mount;
425 
426 	/*
427 	 * Only root, or the user that did the original mount is
428 	 * permitted to unmount this filesystem.
429 	 */
430 	if ((mp->mnt_stat.f_owner != p->p_ucred->cr_uid) &&
431 	    (error = suser(p))) {
432 		vput(vp);
433 		return (error);
434 	}
435 
436 	/*
437 	 * Don't allow unmounting the root file system.
438 	 */
439 	if (mp->mnt_flag & MNT_ROOTFS) {
440 		vput(vp);
441 		return (EINVAL);
442 	}
443 
444 	/*
445 	 * Must be the root of the filesystem
446 	 */
447 	if ((vp->v_flag & VROOT) == 0) {
448 		vput(vp);
449 		return (EINVAL);
450 	}
451 	vput(vp);
452 	return (dounmount(mp, SCARG(uap, flags), p));
453 }
454 
455 /*
456  * Do the actual file system unmount.
457  */
458 int
459 dounmount(mp, flags, p)
460 	register struct mount *mp;
461 	int flags;
462 	struct proc *p;
463 {
464 	struct vnode *coveredvp;
465 	int error;
466 	int async_flag;
467 
468 	simple_lock(&mountlist_slock);
469 	mp->mnt_kern_flag |= MNTK_UNMOUNT;
470 	lockmgr(&mp->mnt_lock, LK_DRAIN | LK_INTERLOCK, &mountlist_slock, p);
471 
472 	if (mp->mnt_flag & MNT_EXPUBLIC)
473 		vfs_setpublicfs(NULL, NULL, NULL);
474 
475 	vfs_msync(mp, MNT_WAIT);
476 	async_flag = mp->mnt_flag & MNT_ASYNC;
477 	mp->mnt_flag &=~ MNT_ASYNC;
478 	cache_purgevfs(mp);	/* remove cache entries for this file sys */
479 	if (mp->mnt_syncer != NULL)
480 		vrele(mp->mnt_syncer);
481 	if (((mp->mnt_flag & MNT_RDONLY) ||
482 	     (error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p)) == 0) ||
483 	    (flags & MNT_FORCE))
484 		error = VFS_UNMOUNT(mp, flags, p);
485 	simple_lock(&mountlist_slock);
486 	if (error) {
487 		if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL)
488 			(void) vfs_allocate_syncvnode(mp);
489 		mp->mnt_kern_flag &= ~MNTK_UNMOUNT;
490 		mp->mnt_flag |= async_flag;
491 		lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK | LK_REENABLE,
492 		    &mountlist_slock, p);
493 		if (mp->mnt_kern_flag & MNTK_MWAIT)
494 			wakeup((caddr_t)mp);
495 		return (error);
496 	}
497 	CIRCLEQ_REMOVE(&mountlist, mp, mnt_list);
498 	if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) {
499 		coveredvp->v_mountedhere = (struct mount *)0;
500 		vrele(coveredvp);
501 	}
502 	mp->mnt_vfc->vfc_refcount--;
503 	if (mp->mnt_vnodelist.lh_first != NULL)
504 		panic("unmount: dangling vnode");
505 	lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_slock, p);
506 	if (mp->mnt_kern_flag & MNTK_MWAIT)
507 		wakeup((caddr_t)mp);
508 	free((caddr_t)mp, M_MOUNT);
509 	return (0);
510 }
511 
512 /*
513  * Sync each mounted filesystem.
514  */
515 #ifndef _SYS_SYSPROTO_H_
516 struct sync_args {
517         int     dummy;
518 };
519 #endif
520 
521 #ifdef DEBUG
522 static int syncprt = 0;
523 SYSCTL_INT(_debug, OID_AUTO, syncprt, CTLFLAG_RW, &syncprt, 0, "");
524 #endif
525 
526 /* ARGSUSED */
527 int
528 sync(p, uap)
529 	struct proc *p;
530 	struct sync_args *uap;
531 {
532 	register struct mount *mp, *nmp;
533 	int asyncflag;
534 
535 	simple_lock(&mountlist_slock);
536 	for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) {
537 		if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) {
538 			nmp = mp->mnt_list.cqe_next;
539 			continue;
540 		}
541 		if ((mp->mnt_flag & MNT_RDONLY) == 0) {
542 			asyncflag = mp->mnt_flag & MNT_ASYNC;
543 			mp->mnt_flag &= ~MNT_ASYNC;
544 			vfs_msync(mp, MNT_NOWAIT);
545 			VFS_SYNC(mp, MNT_NOWAIT,
546 				((p != NULL) ? p->p_ucred : NOCRED), p);
547 			mp->mnt_flag |= asyncflag;
548 		}
549 		simple_lock(&mountlist_slock);
550 		nmp = mp->mnt_list.cqe_next;
551 		vfs_unbusy(mp, p);
552 	}
553 	simple_unlock(&mountlist_slock);
554 #if 0
555 /*
556  * XXX don't call vfs_bufstats() yet because that routine
557  * was not imported in the Lite2 merge.
558  */
559 #ifdef DIAGNOSTIC
560 	if (syncprt)
561 		vfs_bufstats();
562 #endif /* DIAGNOSTIC */
563 #endif
564 	return (0);
565 }
566 
567 /* XXX PRISON: could be per prison flag */
568 static int prison_quotas;
569 #if 0
570 SYSCTL_INT(_kern_prison, OID_AUTO, quotas, CTLFLAG_RW, &prison_quotas, 0, "");
571 #endif
572 
573 /*
574  * Change filesystem quotas.
575  */
576 #ifndef _SYS_SYSPROTO_H_
577 struct quotactl_args {
578 	char *path;
579 	int cmd;
580 	int uid;
581 	caddr_t arg;
582 };
583 #endif
584 /* ARGSUSED */
585 int
586 quotactl(p, uap)
587 	struct proc *p;
588 	register struct quotactl_args /* {
589 		syscallarg(char *) path;
590 		syscallarg(int) cmd;
591 		syscallarg(int) uid;
592 		syscallarg(caddr_t) arg;
593 	} */ *uap;
594 {
595 	register struct mount *mp;
596 	int error;
597 	struct nameidata nd;
598 
599 	if (p->p_prison && !prison_quotas)
600 		return (EPERM);
601 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
602 	if ((error = namei(&nd)) != 0)
603 		return (error);
604 	mp = nd.ni_vp->v_mount;
605 	vrele(nd.ni_vp);
606 	return (VFS_QUOTACTL(mp, SCARG(uap, cmd), SCARG(uap, uid),
607 	    SCARG(uap, arg), p));
608 }
609 
610 /*
611  * Get filesystem statistics.
612  */
613 #ifndef _SYS_SYSPROTO_H_
614 struct statfs_args {
615 	char *path;
616 	struct statfs *buf;
617 };
618 #endif
619 /* ARGSUSED */
620 int
621 statfs(p, uap)
622 	struct proc *p;
623 	register struct statfs_args /* {
624 		syscallarg(char *) path;
625 		syscallarg(struct statfs *) buf;
626 	} */ *uap;
627 {
628 	register struct mount *mp;
629 	register struct statfs *sp;
630 	int error;
631 	struct nameidata nd;
632 	struct statfs sb;
633 
634 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
635 	if ((error = namei(&nd)) != 0)
636 		return (error);
637 	mp = nd.ni_vp->v_mount;
638 	sp = &mp->mnt_stat;
639 	vrele(nd.ni_vp);
640 	error = VFS_STATFS(mp, sp, p);
641 	if (error)
642 		return (error);
643 	sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
644 	if (suser_xxx(p->p_ucred, 0, 0)) {
645 		bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
646 		sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
647 		sp = &sb;
648 	}
649 	return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp)));
650 }
651 
652 /*
653  * Get filesystem statistics.
654  */
655 #ifndef _SYS_SYSPROTO_H_
656 struct fstatfs_args {
657 	int fd;
658 	struct statfs *buf;
659 };
660 #endif
661 /* ARGSUSED */
662 int
663 fstatfs(p, uap)
664 	struct proc *p;
665 	register struct fstatfs_args /* {
666 		syscallarg(int) fd;
667 		syscallarg(struct statfs *) buf;
668 	} */ *uap;
669 {
670 	struct file *fp;
671 	struct mount *mp;
672 	register struct statfs *sp;
673 	int error;
674 	struct statfs sb;
675 
676 	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
677 		return (error);
678 	mp = ((struct vnode *)fp->f_data)->v_mount;
679 	sp = &mp->mnt_stat;
680 	error = VFS_STATFS(mp, sp, p);
681 	if (error)
682 		return (error);
683 	sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
684 	if (suser_xxx(p->p_ucred, 0, 0)) {
685 		bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
686 		sb.f_fsid.val[0] = sb.f_fsid.val[1] = 0;
687 		sp = &sb;
688 	}
689 	return (copyout((caddr_t)sp, (caddr_t)SCARG(uap, buf), sizeof(*sp)));
690 }
691 
692 /*
693  * Get statistics on all filesystems.
694  */
695 #ifndef _SYS_SYSPROTO_H_
696 struct getfsstat_args {
697 	struct statfs *buf;
698 	long bufsize;
699 	int flags;
700 };
701 #endif
702 int
703 getfsstat(p, uap)
704 	struct proc *p;
705 	register struct getfsstat_args /* {
706 		syscallarg(struct statfs *) buf;
707 		syscallarg(long) bufsize;
708 		syscallarg(int) flags;
709 	} */ *uap;
710 {
711 	register struct mount *mp, *nmp;
712 	register struct statfs *sp;
713 	caddr_t sfsp;
714 	long count, maxcount, error;
715 
716 	maxcount = SCARG(uap, bufsize) / sizeof(struct statfs);
717 	sfsp = (caddr_t)SCARG(uap, buf);
718 	count = 0;
719 	simple_lock(&mountlist_slock);
720 	for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) {
721 		if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) {
722 			nmp = mp->mnt_list.cqe_next;
723 			continue;
724 		}
725 		if (sfsp && count < maxcount) {
726 			sp = &mp->mnt_stat;
727 			/*
728 			 * If MNT_NOWAIT or MNT_LAZY is specified, do not
729 			 * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
730 			 * overrides MNT_WAIT.
731 			 */
732 			if (((SCARG(uap, flags) & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
733 			    (SCARG(uap, flags) & MNT_WAIT)) &&
734 			    (error = VFS_STATFS(mp, sp, p))) {
735 				simple_lock(&mountlist_slock);
736 				nmp = mp->mnt_list.cqe_next;
737 				vfs_unbusy(mp, p);
738 				continue;
739 			}
740 			sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
741 			error = copyout((caddr_t)sp, sfsp, sizeof(*sp));
742 			if (error) {
743 				vfs_unbusy(mp, p);
744 				return (error);
745 			}
746 			sfsp += sizeof(*sp);
747 		}
748 		count++;
749 		simple_lock(&mountlist_slock);
750 		nmp = mp->mnt_list.cqe_next;
751 		vfs_unbusy(mp, p);
752 	}
753 	simple_unlock(&mountlist_slock);
754 	if (sfsp && count > maxcount)
755 		p->p_retval[0] = maxcount;
756 	else
757 		p->p_retval[0] = count;
758 	return (0);
759 }
760 
761 /*
762  * Change current working directory to a given file descriptor.
763  */
764 #ifndef _SYS_SYSPROTO_H_
765 struct fchdir_args {
766 	int	fd;
767 };
768 #endif
769 /* ARGSUSED */
770 int
771 fchdir(p, uap)
772 	struct proc *p;
773 	struct fchdir_args /* {
774 		syscallarg(int) fd;
775 	} */ *uap;
776 {
777 	register struct filedesc *fdp = p->p_fd;
778 	struct vnode *vp, *tdp;
779 	struct mount *mp;
780 	struct file *fp;
781 	int error;
782 
783 	if ((error = getvnode(fdp, SCARG(uap, fd), &fp)) != 0)
784 		return (error);
785 	vp = (struct vnode *)fp->f_data;
786 	VREF(vp);
787 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
788 	if (vp->v_type != VDIR)
789 		error = ENOTDIR;
790 	else
791 		error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
792 	while (!error && (mp = vp->v_mountedhere) != NULL) {
793 		if (vfs_busy(mp, 0, 0, p))
794 			continue;
795 		error = VFS_ROOT(mp, &tdp);
796 		vfs_unbusy(mp, p);
797 		if (error)
798 			break;
799 		vput(vp);
800 		vp = tdp;
801 	}
802 	if (error) {
803 		vput(vp);
804 		return (error);
805 	}
806 	VOP_UNLOCK(vp, 0, p);
807 	vrele(fdp->fd_cdir);
808 	fdp->fd_cdir = vp;
809 	return (0);
810 }
811 
812 /*
813  * Change current working directory (``.'').
814  */
815 #ifndef _SYS_SYSPROTO_H_
816 struct chdir_args {
817 	char	*path;
818 };
819 #endif
820 /* ARGSUSED */
821 int
822 chdir(p, uap)
823 	struct proc *p;
824 	struct chdir_args /* {
825 		syscallarg(char *) path;
826 	} */ *uap;
827 {
828 	register struct filedesc *fdp = p->p_fd;
829 	int error;
830 	struct nameidata nd;
831 
832 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
833 	    SCARG(uap, path), p);
834 	if ((error = change_dir(&nd, p)) != 0)
835 		return (error);
836 	vrele(fdp->fd_cdir);
837 	fdp->fd_cdir = nd.ni_vp;
838 	return (0);
839 }
840 
841 /*
842  * Helper function for raised chroot(2) security function:  Refuse if
843  * any filedescriptors are open directories.
844  */
845 static int
846 chroot_refuse_vdir_fds(fdp)
847 	struct filedesc *fdp;
848 {
849 	struct vnode *vp;
850 	struct file *fp;
851 	int error;
852 	int fd;
853 
854 	for (fd = 0; fd < fdp->fd_nfiles ; fd++) {
855 		error = getvnode(fdp, fd, &fp);
856 		if (error)
857 			continue;
858 		vp = (struct vnode *)fp->f_data;
859 		if (vp->v_type != VDIR)
860 			continue;
861 		return(EPERM);
862 	}
863 	return (0);
864 }
865 
866 /*
867  * This sysctl determines if we will allow a process to chroot(2) if it
868  * has a directory open:
869  *	0: disallowed for all processes.
870  *	1: allowed for processes that were not already chroot(2)'ed.
871  *	2: allowed for all processes.
872  */
873 
874 static int chroot_allow_open_directories = 1;
875 
876 SYSCTL_INT(_kern, OID_AUTO, chroot_allow_open_directories, CTLFLAG_RW,
877      &chroot_allow_open_directories, 0, "");
878 
879 /*
880  * Change notion of root (``/'') directory.
881  */
882 #ifndef _SYS_SYSPROTO_H_
883 struct chroot_args {
884 	char	*path;
885 };
886 #endif
887 /* ARGSUSED */
888 int
889 chroot(p, uap)
890 	struct proc *p;
891 	struct chroot_args /* {
892 		syscallarg(char *) path;
893 	} */ *uap;
894 {
895 	register struct filedesc *fdp = p->p_fd;
896 	int error;
897 	struct nameidata nd;
898 
899 	error = suser_xxx(0, p, PRISON_ROOT);
900 	if (error)
901 		return (error);
902 	if (chroot_allow_open_directories == 0 ||
903 	    (chroot_allow_open_directories == 1 && fdp->fd_rdir != rootvnode))
904 		error = chroot_refuse_vdir_fds(fdp);
905 	if (error)
906 		return (error);
907 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
908 	    SCARG(uap, path), p);
909 	if ((error = change_dir(&nd, p)) != 0)
910 		return (error);
911 	vrele(fdp->fd_rdir);
912 	fdp->fd_rdir = nd.ni_vp;
913 	return (0);
914 }
915 
916 /*
917  * Common routine for chroot and chdir.
918  */
919 static int
920 change_dir(ndp, p)
921 	register struct nameidata *ndp;
922 	struct proc *p;
923 {
924 	struct vnode *vp;
925 	int error;
926 
927 	error = namei(ndp);
928 	if (error)
929 		return (error);
930 	vp = ndp->ni_vp;
931 	if (vp->v_type != VDIR)
932 		error = ENOTDIR;
933 	else
934 		error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
935 	if (error)
936 		vput(vp);
937 	else
938 		VOP_UNLOCK(vp, 0, p);
939 	return (error);
940 }
941 
942 /*
943  * Check permissions, allocate an open file structure,
944  * and call the device open routine if any.
945  */
946 #ifndef _SYS_SYSPROTO_H_
947 struct open_args {
948 	char	*path;
949 	int	flags;
950 	int	mode;
951 };
952 #endif
953 int
954 open(p, uap)
955 	struct proc *p;
956 	register struct open_args /* {
957 		syscallarg(char *) path;
958 		syscallarg(int) flags;
959 		syscallarg(int) mode;
960 	} */ *uap;
961 {
962 	register struct filedesc *fdp = p->p_fd;
963 	register struct file *fp;
964 	register struct vnode *vp;
965 	int cmode, flags, oflags;
966 	struct file *nfp;
967 	int type, indx, error;
968 	struct flock lf;
969 	struct nameidata nd;
970 
971 	oflags = SCARG(uap, flags);
972 	if ((oflags & O_ACCMODE) == O_ACCMODE)
973 		return (EINVAL);
974 	flags = FFLAGS(oflags);
975 	error = falloc(p, &nfp, &indx);
976 	if (error)
977 		return (error);
978 	fp = nfp;
979 	cmode = ((SCARG(uap, mode) &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
980 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
981 	p->p_dupfd = -indx - 1;			/* XXX check for fdopen */
982 	error = vn_open(&nd, flags, cmode);
983 	if (error) {
984 		ffree(fp);
985 		if ((error == ENODEV || error == ENXIO) &&
986 		    p->p_dupfd >= 0 &&			/* XXX from fdopen */
987 		    (error =
988 			dupfdopen(fdp, indx, p->p_dupfd, flags, error)) == 0) {
989 			p->p_retval[0] = indx;
990 			return (0);
991 		}
992 		if (error == ERESTART)
993 			error = EINTR;
994 		fdp->fd_ofiles[indx] = NULL;
995 		return (error);
996 	}
997 	p->p_dupfd = 0;
998 	vp = nd.ni_vp;
999 
1000 	fp->f_data = (caddr_t)vp;
1001 	fp->f_flag = flags & FMASK;
1002 	fp->f_ops = &vnops;
1003 	fp->f_type = (vp->v_type == VFIFO ? DTYPE_FIFO : DTYPE_VNODE);
1004 	if (flags & (O_EXLOCK | O_SHLOCK)) {
1005 		lf.l_whence = SEEK_SET;
1006 		lf.l_start = 0;
1007 		lf.l_len = 0;
1008 		if (flags & O_EXLOCK)
1009 			lf.l_type = F_WRLCK;
1010 		else
1011 			lf.l_type = F_RDLCK;
1012 		type = F_FLOCK;
1013 		if ((flags & FNONBLOCK) == 0)
1014 			type |= F_WAIT;
1015 		VOP_UNLOCK(vp, 0, p);
1016 		if ((error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) != 0) {
1017 			(void) vn_close(vp, fp->f_flag, fp->f_cred, p);
1018 			ffree(fp);
1019 			fdp->fd_ofiles[indx] = NULL;
1020 			return (error);
1021 		}
1022 		vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
1023 		fp->f_flag |= FHASLOCK;
1024 	}
1025 	/* assert that vn_open created a backing object if one is needed */
1026 	KASSERT(!vn_canvmio(vp) || vp->v_object != NULL,
1027 		("open: vmio vnode has no backing object after vn_open"));
1028 	VOP_UNLOCK(vp, 0, p);
1029 	p->p_retval[0] = indx;
1030 	return (0);
1031 }
1032 
1033 #ifdef COMPAT_43
1034 /*
1035  * Create a file.
1036  */
1037 #ifndef _SYS_SYSPROTO_H_
1038 struct ocreat_args {
1039 	char	*path;
1040 	int	mode;
1041 };
1042 #endif
1043 int
1044 ocreat(p, uap)
1045 	struct proc *p;
1046 	register struct ocreat_args /* {
1047 		syscallarg(char *) path;
1048 		syscallarg(int) mode;
1049 	} */ *uap;
1050 {
1051 	struct open_args /* {
1052 		syscallarg(char *) path;
1053 		syscallarg(int) flags;
1054 		syscallarg(int) mode;
1055 	} */ nuap;
1056 
1057 	SCARG(&nuap, path) = SCARG(uap, path);
1058 	SCARG(&nuap, mode) = SCARG(uap, mode);
1059 	SCARG(&nuap, flags) = O_WRONLY | O_CREAT | O_TRUNC;
1060 	return (open(p, &nuap));
1061 }
1062 #endif /* COMPAT_43 */
1063 
1064 /*
1065  * Create a special file.
1066  */
1067 #ifndef _SYS_SYSPROTO_H_
1068 struct mknod_args {
1069 	char	*path;
1070 	int	mode;
1071 	int	dev;
1072 };
1073 #endif
1074 /* ARGSUSED */
1075 int
1076 mknod(p, uap)
1077 	struct proc *p;
1078 	register struct mknod_args /* {
1079 		syscallarg(char *) path;
1080 		syscallarg(int) mode;
1081 		syscallarg(int) dev;
1082 	} */ *uap;
1083 {
1084 	register struct vnode *vp;
1085 	struct vattr vattr;
1086 	int error;
1087 	int whiteout = 0;
1088 	struct nameidata nd;
1089 
1090 	switch (SCARG(uap, mode) & S_IFMT) {
1091 	case S_IFCHR:
1092 	case S_IFBLK:
1093 		error = suser(p);
1094 		break;
1095 	default:
1096 		error = suser_xxx(0, p, PRISON_ROOT);
1097 		break;
1098 	}
1099 	if (error)
1100 		return (error);
1101 	NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p);
1102 	if ((error = namei(&nd)) != 0)
1103 		return (error);
1104 	vp = nd.ni_vp;
1105 	if (vp != NULL)
1106 		error = EEXIST;
1107 	else {
1108 		VATTR_NULL(&vattr);
1109 		vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask;
1110 		vattr.va_rdev = SCARG(uap, dev);
1111 		whiteout = 0;
1112 
1113 		switch (SCARG(uap, mode) & S_IFMT) {
1114 		case S_IFMT:	/* used by badsect to flag bad sectors */
1115 			vattr.va_type = VBAD;
1116 			break;
1117 		case S_IFCHR:
1118 			vattr.va_type = VCHR;
1119 			break;
1120 		case S_IFBLK:
1121 			vattr.va_type = VBLK;
1122 			break;
1123 		case S_IFWHT:
1124 			whiteout = 1;
1125 			break;
1126 		default:
1127 			error = EINVAL;
1128 			break;
1129 		}
1130 	}
1131 	if (!error) {
1132 		VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
1133 		if (whiteout) {
1134 			error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, CREATE);
1135 			if (error)
1136 				VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1137 			vput(nd.ni_dvp);
1138 		} else {
1139 			error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp,
1140 						&nd.ni_cnd, &vattr);
1141 			vput(nd.ni_dvp);
1142 		}
1143 	} else {
1144 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1145 		if (nd.ni_dvp == vp)
1146 			vrele(nd.ni_dvp);
1147 		else
1148 			vput(nd.ni_dvp);
1149 		if (vp)
1150 			vrele(vp);
1151 	}
1152 	ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mknod");
1153 	ASSERT_VOP_UNLOCKED(nd.ni_vp, "mknod");
1154 	return (error);
1155 }
1156 
1157 /*
1158  * Create a named pipe.
1159  */
1160 #ifndef _SYS_SYSPROTO_H_
1161 struct mkfifo_args {
1162 	char	*path;
1163 	int	mode;
1164 };
1165 #endif
1166 /* ARGSUSED */
1167 int
1168 mkfifo(p, uap)
1169 	struct proc *p;
1170 	register struct mkfifo_args /* {
1171 		syscallarg(char *) path;
1172 		syscallarg(int) mode;
1173 	} */ *uap;
1174 {
1175 	struct vattr vattr;
1176 	int error;
1177 	struct nameidata nd;
1178 
1179 	NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p);
1180 	if ((error = namei(&nd)) != 0)
1181 		return (error);
1182 	if (nd.ni_vp != NULL) {
1183 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1184 		if (nd.ni_dvp == nd.ni_vp)
1185 			vrele(nd.ni_dvp);
1186 		else
1187 			vput(nd.ni_dvp);
1188 		vrele(nd.ni_vp);
1189 		return (EEXIST);
1190 	}
1191 	VATTR_NULL(&vattr);
1192 	vattr.va_type = VFIFO;
1193 	vattr.va_mode = (SCARG(uap, mode) & ALLPERMS) &~ p->p_fd->fd_cmask;
1194 	VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
1195 	error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
1196 	vput(nd.ni_dvp);
1197 	return (error);
1198 }
1199 
1200 /*
1201  * Make a hard file link.
1202  */
1203 #ifndef _SYS_SYSPROTO_H_
1204 struct link_args {
1205 	char	*path;
1206 	char	*link;
1207 };
1208 #endif
1209 /* ARGSUSED */
1210 int
1211 link(p, uap)
1212 	struct proc *p;
1213 	register struct link_args /* {
1214 		syscallarg(char *) path;
1215 		syscallarg(char *) link;
1216 	} */ *uap;
1217 {
1218 	register struct vnode *vp;
1219 	struct nameidata nd;
1220 	int error;
1221 
1222 	NDINIT(&nd, LOOKUP, FOLLOW|NOOBJ, UIO_USERSPACE, SCARG(uap, path), p);
1223 	if ((error = namei(&nd)) != 0)
1224 		return (error);
1225 	vp = nd.ni_vp;
1226 	if (vp->v_type == VDIR)
1227 		error = EPERM;		/* POSIX */
1228 	else {
1229 		NDINIT(&nd, CREATE, LOCKPARENT|NOOBJ, UIO_USERSPACE, SCARG(uap, link), p);
1230 		error = namei(&nd);
1231 		if (!error) {
1232 			if (nd.ni_vp != NULL) {
1233 				VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1234 				if (nd.ni_vp)
1235 					vrele(nd.ni_vp);
1236 				error = EEXIST;
1237 			} else {
1238 				VOP_LEASE(nd.ni_dvp, p, p->p_ucred,
1239 				    LEASE_WRITE);
1240 				VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
1241 				error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
1242 			}
1243 			if (nd.ni_dvp == nd.ni_vp)
1244 				vrele(nd.ni_dvp);
1245 			else
1246 				vput(nd.ni_dvp);
1247 		}
1248 	}
1249 	vrele(vp);
1250 	ASSERT_VOP_UNLOCKED(nd.ni_dvp, "link");
1251 	ASSERT_VOP_UNLOCKED(nd.ni_vp, "link");
1252 	return (error);
1253 }
1254 
1255 /*
1256  * Make a symbolic link.
1257  */
1258 #ifndef _SYS_SYSPROTO_H_
1259 struct symlink_args {
1260 	char	*path;
1261 	char	*link;
1262 };
1263 #endif
1264 /* ARGSUSED */
1265 int
1266 symlink(p, uap)
1267 	struct proc *p;
1268 	register struct symlink_args /* {
1269 		syscallarg(char *) path;
1270 		syscallarg(char *) link;
1271 	} */ *uap;
1272 {
1273 	struct vattr vattr;
1274 	char *path;
1275 	int error;
1276 	struct nameidata nd;
1277 
1278 	path = zalloc(namei_zone);
1279 	if ((error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, NULL)) != 0)
1280 		goto out;
1281 	NDINIT(&nd, CREATE, LOCKPARENT|NOOBJ, UIO_USERSPACE, SCARG(uap, link), p);
1282 	if ((error = namei(&nd)) != 0)
1283 		goto out;
1284 	if (nd.ni_vp) {
1285 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1286 		if (nd.ni_dvp == nd.ni_vp)
1287 			vrele(nd.ni_dvp);
1288 		else
1289 			vput(nd.ni_dvp);
1290 		vrele(nd.ni_vp);
1291 		error = EEXIST;
1292 		goto out;
1293 	}
1294 	VATTR_NULL(&vattr);
1295 	vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask;
1296 	VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
1297 	error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path);
1298 	vput(nd.ni_dvp);
1299 	ASSERT_VOP_UNLOCKED(nd.ni_dvp, "symlink");
1300 	ASSERT_VOP_UNLOCKED(nd.ni_vp, "symlink");
1301 out:
1302 	zfree(namei_zone, path);
1303 	return (error);
1304 }
1305 
1306 /*
1307  * Delete a whiteout from the filesystem.
1308  */
1309 /* ARGSUSED */
1310 int
1311 undelete(p, uap)
1312 	struct proc *p;
1313 	register struct undelete_args /* {
1314 		syscallarg(char *) path;
1315 	} */ *uap;
1316 {
1317 	int error;
1318 	struct nameidata nd;
1319 
1320 	NDINIT(&nd, DELETE, LOCKPARENT|DOWHITEOUT, UIO_USERSPACE,
1321 	    SCARG(uap, path), p);
1322 	error = namei(&nd);
1323 	if (error)
1324 		return (error);
1325 
1326 	if (nd.ni_vp != NULLVP || !(nd.ni_cnd.cn_flags & ISWHITEOUT)) {
1327 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1328 		if (nd.ni_dvp == nd.ni_vp)
1329 			vrele(nd.ni_dvp);
1330 		else
1331 			vput(nd.ni_dvp);
1332 		if (nd.ni_vp)
1333 			vrele(nd.ni_vp);
1334 		return (EEXIST);
1335 	}
1336 
1337 	VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
1338 	if ((error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE)) != 0)
1339 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1340 	vput(nd.ni_dvp);
1341 	ASSERT_VOP_UNLOCKED(nd.ni_dvp, "undelete");
1342 	ASSERT_VOP_UNLOCKED(nd.ni_vp, "undelete");
1343 	return (error);
1344 }
1345 
1346 /*
1347  * Delete a name from the filesystem.
1348  */
1349 #ifndef _SYS_SYSPROTO_H_
1350 struct unlink_args {
1351 	char	*path;
1352 };
1353 #endif
1354 /* ARGSUSED */
1355 int
1356 unlink(p, uap)
1357 	struct proc *p;
1358 	struct unlink_args /* {
1359 		syscallarg(char *) path;
1360 	} */ *uap;
1361 {
1362 	register struct vnode *vp;
1363 	int error;
1364 	struct nameidata nd;
1365 
1366 	NDINIT(&nd, DELETE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p);
1367 	if ((error = namei(&nd)) != 0)
1368 		return (error);
1369 	vp = nd.ni_vp;
1370 	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
1371 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
1372 
1373 	if (vp->v_type == VDIR)
1374 		error = EPERM;		/* POSIX */
1375 	else {
1376 		/*
1377 		 * The root of a mounted filesystem cannot be deleted.
1378 		 *
1379 		 * XXX: can this only be a VDIR case?
1380 		 */
1381 		if (vp->v_flag & VROOT)
1382 			error = EBUSY;
1383 	}
1384 
1385 	if (!error) {
1386 		VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
1387 		error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd);
1388 	} else {
1389 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1390 	}
1391 	if (nd.ni_dvp == vp)
1392 		vrele(nd.ni_dvp);
1393 	else
1394 		vput(nd.ni_dvp);
1395 	if (vp != NULLVP)
1396 		vput(vp);
1397 	ASSERT_VOP_UNLOCKED(nd.ni_dvp, "unlink");
1398 	ASSERT_VOP_UNLOCKED(nd.ni_vp, "unlink");
1399 	return (error);
1400 }
1401 
1402 /*
1403  * Reposition read/write file offset.
1404  */
1405 #ifndef _SYS_SYSPROTO_H_
1406 struct lseek_args {
1407 	int	fd;
1408 	int	pad;
1409 	off_t	offset;
1410 	int	whence;
1411 };
1412 #endif
1413 int
1414 lseek(p, uap)
1415 	struct proc *p;
1416 	register struct lseek_args /* {
1417 		syscallarg(int) fd;
1418 		syscallarg(int) pad;
1419 		syscallarg(off_t) offset;
1420 		syscallarg(int) whence;
1421 	} */ *uap;
1422 {
1423 	struct ucred *cred = p->p_ucred;
1424 	register struct filedesc *fdp = p->p_fd;
1425 	register struct file *fp;
1426 	struct vattr vattr;
1427 	int error;
1428 
1429 	if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
1430 	    (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
1431 		return (EBADF);
1432 	if (fp->f_type != DTYPE_VNODE)
1433 		return (ESPIPE);
1434 	switch (SCARG(uap, whence)) {
1435 	case L_INCR:
1436 		fp->f_offset += SCARG(uap, offset);
1437 		break;
1438 	case L_XTND:
1439 		error=VOP_GETATTR((struct vnode *)fp->f_data, &vattr, cred, p);
1440 		if (error)
1441 			return (error);
1442 		fp->f_offset = SCARG(uap, offset) + vattr.va_size;
1443 		break;
1444 	case L_SET:
1445 		fp->f_offset = SCARG(uap, offset);
1446 		break;
1447 	default:
1448 		return (EINVAL);
1449 	}
1450 	*(off_t *)(p->p_retval) = fp->f_offset;
1451 	return (0);
1452 }
1453 
1454 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1455 /*
1456  * Reposition read/write file offset.
1457  */
1458 #ifndef _SYS_SYSPROTO_H_
1459 struct olseek_args {
1460 	int	fd;
1461 	long	offset;
1462 	int	whence;
1463 };
1464 #endif
1465 int
1466 olseek(p, uap)
1467 	struct proc *p;
1468 	register struct olseek_args /* {
1469 		syscallarg(int) fd;
1470 		syscallarg(long) offset;
1471 		syscallarg(int) whence;
1472 	} */ *uap;
1473 {
1474 	struct lseek_args /* {
1475 		syscallarg(int) fd;
1476 		syscallarg(int) pad;
1477 		syscallarg(off_t) offset;
1478 		syscallarg(int) whence;
1479 	} */ nuap;
1480 	int error;
1481 
1482 	SCARG(&nuap, fd) = SCARG(uap, fd);
1483 	SCARG(&nuap, offset) = SCARG(uap, offset);
1484 	SCARG(&nuap, whence) = SCARG(uap, whence);
1485 	error = lseek(p, &nuap);
1486 	return (error);
1487 }
1488 #endif /* COMPAT_43 */
1489 
1490 /*
1491  * Check access permissions.
1492  */
1493 #ifndef _SYS_SYSPROTO_H_
1494 struct access_args {
1495 	char	*path;
1496 	int	flags;
1497 };
1498 #endif
1499 int
1500 access(p, uap)
1501 	struct proc *p;
1502 	register struct access_args /* {
1503 		syscallarg(char *) path;
1504 		syscallarg(int) flags;
1505 	} */ *uap;
1506 {
1507 	register struct ucred *cred = p->p_ucred;
1508 	register struct vnode *vp;
1509 	int error, flags, t_gid, t_uid;
1510 	struct nameidata nd;
1511 
1512 	t_uid = cred->cr_uid;
1513 	t_gid = cred->cr_groups[0];
1514 	cred->cr_uid = p->p_cred->p_ruid;
1515 	cred->cr_groups[0] = p->p_cred->p_rgid;
1516 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1517 	    SCARG(uap, path), p);
1518 	if ((error = namei(&nd)) != 0)
1519 		goto out1;
1520 	vp = nd.ni_vp;
1521 
1522 	/* Flags == 0 means only check for existence. */
1523 	if (SCARG(uap, flags)) {
1524 		flags = 0;
1525 		if (SCARG(uap, flags) & R_OK)
1526 			flags |= VREAD;
1527 		if (SCARG(uap, flags) & W_OK)
1528 			flags |= VWRITE;
1529 		if (SCARG(uap, flags) & X_OK)
1530 			flags |= VEXEC;
1531 		if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
1532 			error = VOP_ACCESS(vp, flags, cred, p);
1533 	}
1534 	vput(vp);
1535 out1:
1536 	cred->cr_uid = t_uid;
1537 	cred->cr_groups[0] = t_gid;
1538 	return (error);
1539 }
1540 
1541 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1542 /*
1543  * Get file status; this version follows links.
1544  */
1545 #ifndef _SYS_SYSPROTO_H_
1546 struct ostat_args {
1547 	char	*path;
1548 	struct ostat *ub;
1549 };
1550 #endif
1551 /* ARGSUSED */
1552 int
1553 ostat(p, uap)
1554 	struct proc *p;
1555 	register struct ostat_args /* {
1556 		syscallarg(char *) path;
1557 		syscallarg(struct ostat *) ub;
1558 	} */ *uap;
1559 {
1560 	struct stat sb;
1561 	struct ostat osb;
1562 	int error;
1563 	struct nameidata nd;
1564 
1565 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1566 	    SCARG(uap, path), p);
1567 	if ((error = namei(&nd)) != 0)
1568 		return (error);
1569 	error = vn_stat(nd.ni_vp, &sb, p);
1570 	vput(nd.ni_vp);
1571 	if (error)
1572 		return (error);
1573 	cvtstat(&sb, &osb);
1574 	error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
1575 	return (error);
1576 }
1577 
1578 /*
1579  * Get file status; this version does not follow links.
1580  */
1581 #ifndef _SYS_SYSPROTO_H_
1582 struct olstat_args {
1583 	char	*path;
1584 	struct ostat *ub;
1585 };
1586 #endif
1587 /* ARGSUSED */
1588 int
1589 olstat(p, uap)
1590 	struct proc *p;
1591 	register struct olstat_args /* {
1592 		syscallarg(char *) path;
1593 		syscallarg(struct ostat *) ub;
1594 	} */ *uap;
1595 {
1596 	struct vnode *vp;
1597 	struct stat sb;
1598 	struct ostat osb;
1599 	int error;
1600 	struct nameidata nd;
1601 
1602 	NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1603 	    SCARG(uap, path), p);
1604 	if ((error = namei(&nd)) != 0)
1605 		return (error);
1606 	vp = nd.ni_vp;
1607 	error = vn_stat(vp, &sb, p);
1608 	vput(vp);
1609 	if (error)
1610 		return (error);
1611 	cvtstat(&sb, &osb);
1612 	error = copyout((caddr_t)&osb, (caddr_t)SCARG(uap, ub), sizeof (osb));
1613 	return (error);
1614 }
1615 
1616 /*
1617  * Convert from an old to a new stat structure.
1618  */
1619 void
1620 cvtstat(st, ost)
1621 	struct stat *st;
1622 	struct ostat *ost;
1623 {
1624 
1625 	ost->st_dev = st->st_dev;
1626 	ost->st_ino = st->st_ino;
1627 	ost->st_mode = st->st_mode;
1628 	ost->st_nlink = st->st_nlink;
1629 	ost->st_uid = st->st_uid;
1630 	ost->st_gid = st->st_gid;
1631 	ost->st_rdev = st->st_rdev;
1632 	if (st->st_size < (quad_t)1 << 32)
1633 		ost->st_size = st->st_size;
1634 	else
1635 		ost->st_size = -2;
1636 	ost->st_atime = st->st_atime;
1637 	ost->st_mtime = st->st_mtime;
1638 	ost->st_ctime = st->st_ctime;
1639 	ost->st_blksize = st->st_blksize;
1640 	ost->st_blocks = st->st_blocks;
1641 	ost->st_flags = st->st_flags;
1642 	ost->st_gen = st->st_gen;
1643 }
1644 #endif /* COMPAT_43 || COMPAT_SUNOS */
1645 
1646 /*
1647  * Get file status; this version follows links.
1648  */
1649 #ifndef _SYS_SYSPROTO_H_
1650 struct stat_args {
1651 	char	*path;
1652 	struct stat *ub;
1653 };
1654 #endif
1655 /* ARGSUSED */
1656 int
1657 stat(p, uap)
1658 	struct proc *p;
1659 	register struct stat_args /* {
1660 		syscallarg(char *) path;
1661 		syscallarg(struct stat *) ub;
1662 	} */ *uap;
1663 {
1664 	struct stat sb;
1665 	int error;
1666 	struct nameidata nd;
1667 
1668 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1669 	    SCARG(uap, path), p);
1670 	if ((error = namei(&nd)) != 0)
1671 		return (error);
1672 	error = vn_stat(nd.ni_vp, &sb, p);
1673 	vput(nd.ni_vp);
1674 	if (error)
1675 		return (error);
1676 	error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb));
1677 	return (error);
1678 }
1679 
1680 /*
1681  * Get file status; this version does not follow links.
1682  */
1683 #ifndef _SYS_SYSPROTO_H_
1684 struct lstat_args {
1685 	char	*path;
1686 	struct stat *ub;
1687 };
1688 #endif
1689 /* ARGSUSED */
1690 int
1691 lstat(p, uap)
1692 	struct proc *p;
1693 	register struct lstat_args /* {
1694 		syscallarg(char *) path;
1695 		syscallarg(struct stat *) ub;
1696 	} */ *uap;
1697 {
1698 	int error;
1699 	struct vnode *vp;
1700 	struct stat sb;
1701 	struct nameidata nd;
1702 
1703 	NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1704 	    SCARG(uap, path), p);
1705 	if ((error = namei(&nd)) != 0)
1706 		return (error);
1707 	vp = nd.ni_vp;
1708 	error = vn_stat(vp, &sb, p);
1709 	vput(vp);
1710 	if (error)
1711 		return (error);
1712 	error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb));
1713 	return (error);
1714 }
1715 
1716 void
1717 cvtnstat(sb, nsb)
1718 	struct stat *sb;
1719 	struct nstat *nsb;
1720 {
1721 	nsb->st_dev = sb->st_dev;
1722 	nsb->st_ino = sb->st_ino;
1723 	nsb->st_mode = sb->st_mode;
1724 	nsb->st_nlink = sb->st_nlink;
1725 	nsb->st_uid = sb->st_uid;
1726 	nsb->st_gid = sb->st_gid;
1727 	nsb->st_rdev = sb->st_rdev;
1728 	nsb->st_atimespec = sb->st_atimespec;
1729 	nsb->st_mtimespec = sb->st_mtimespec;
1730 	nsb->st_ctimespec = sb->st_ctimespec;
1731 	nsb->st_size = sb->st_size;
1732 	nsb->st_blocks = sb->st_blocks;
1733 	nsb->st_blksize = sb->st_blksize;
1734 	nsb->st_flags = sb->st_flags;
1735 	nsb->st_gen = sb->st_gen;
1736 }
1737 
1738 #ifndef _SYS_SYSPROTO_H_
1739 struct nstat_args {
1740 	char	*path;
1741 	struct nstat *ub;
1742 };
1743 #endif
1744 /* ARGSUSED */
1745 int
1746 nstat(p, uap)
1747 	struct proc *p;
1748 	register struct nstat_args /* {
1749 		syscallarg(char *) path;
1750 		syscallarg(struct nstat *) ub;
1751 	} */ *uap;
1752 {
1753 	struct stat sb;
1754 	struct nstat nsb;
1755 	int error;
1756 	struct nameidata nd;
1757 
1758 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1759 	    SCARG(uap, path), p);
1760 	if ((error = namei(&nd)) != 0)
1761 		return (error);
1762 	error = vn_stat(nd.ni_vp, &sb, p);
1763 	vput(nd.ni_vp);
1764 	if (error)
1765 		return (error);
1766 	cvtnstat(&sb, &nsb);
1767 	error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb));
1768 	return (error);
1769 }
1770 
1771 /*
1772  * Get file status; this version does not follow links.
1773  */
1774 #ifndef _SYS_SYSPROTO_H_
1775 struct lstat_args {
1776 	char	*path;
1777 	struct stat *ub;
1778 };
1779 #endif
1780 /* ARGSUSED */
1781 int
1782 nlstat(p, uap)
1783 	struct proc *p;
1784 	register struct nlstat_args /* {
1785 		syscallarg(char *) path;
1786 		syscallarg(struct nstat *) ub;
1787 	} */ *uap;
1788 {
1789 	int error;
1790 	struct vnode *vp;
1791 	struct stat sb;
1792 	struct nstat nsb;
1793 	struct nameidata nd;
1794 
1795 	NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1796 	    SCARG(uap, path), p);
1797 	if ((error = namei(&nd)) != 0)
1798 		return (error);
1799 	vp = nd.ni_vp;
1800 	error = vn_stat(vp, &sb, p);
1801 	vput(vp);
1802 	if (error)
1803 		return (error);
1804 	cvtnstat(&sb, &nsb);
1805 	error = copyout((caddr_t)&nsb, (caddr_t)SCARG(uap, ub), sizeof (nsb));
1806 	return (error);
1807 }
1808 
1809 /*
1810  * Get configurable pathname variables.
1811  */
1812 #ifndef _SYS_SYSPROTO_H_
1813 struct pathconf_args {
1814 	char	*path;
1815 	int	name;
1816 };
1817 #endif
1818 /* ARGSUSED */
1819 int
1820 pathconf(p, uap)
1821 	struct proc *p;
1822 	register struct pathconf_args /* {
1823 		syscallarg(char *) path;
1824 		syscallarg(int) name;
1825 	} */ *uap;
1826 {
1827 	int error;
1828 	struct nameidata nd;
1829 
1830 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1831 	    SCARG(uap, path), p);
1832 	if ((error = namei(&nd)) != 0)
1833 		return (error);
1834 	error = VOP_PATHCONF(nd.ni_vp, SCARG(uap, name), p->p_retval);
1835 	vput(nd.ni_vp);
1836 	return (error);
1837 }
1838 
1839 /*
1840  * Return target name of a symbolic link.
1841  */
1842 #ifndef _SYS_SYSPROTO_H_
1843 struct readlink_args {
1844 	char	*path;
1845 	char	*buf;
1846 	int	count;
1847 };
1848 #endif
1849 /* ARGSUSED */
1850 int
1851 readlink(p, uap)
1852 	struct proc *p;
1853 	register struct readlink_args /* {
1854 		syscallarg(char *) path;
1855 		syscallarg(char *) buf;
1856 		syscallarg(int) count;
1857 	} */ *uap;
1858 {
1859 	register struct vnode *vp;
1860 	struct iovec aiov;
1861 	struct uio auio;
1862 	int error;
1863 	struct nameidata nd;
1864 
1865 	NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
1866 	    SCARG(uap, path), p);
1867 	if ((error = namei(&nd)) != 0)
1868 		return (error);
1869 	vp = nd.ni_vp;
1870 	if (vp->v_type != VLNK)
1871 		error = EINVAL;
1872 	else {
1873 		aiov.iov_base = SCARG(uap, buf);
1874 		aiov.iov_len = SCARG(uap, count);
1875 		auio.uio_iov = &aiov;
1876 		auio.uio_iovcnt = 1;
1877 		auio.uio_offset = 0;
1878 		auio.uio_rw = UIO_READ;
1879 		auio.uio_segflg = UIO_USERSPACE;
1880 		auio.uio_procp = p;
1881 		auio.uio_resid = SCARG(uap, count);
1882 		error = VOP_READLINK(vp, &auio, p->p_ucred);
1883 	}
1884 	vput(vp);
1885 	p->p_retval[0] = SCARG(uap, count) - auio.uio_resid;
1886 	return (error);
1887 }
1888 
1889 static int
1890 setfflags(p, vp, flags)
1891 	struct proc *p;
1892 	struct vnode *vp;
1893 	int flags;
1894 {
1895 	int error;
1896 	struct vattr vattr;
1897 
1898 	/*
1899 	 * Prevent non-root users from setting flags on devices.  When
1900 	 * a device is reused, users can retain ownership of the device
1901 	 * if they are allowed to set flags and programs assume that
1902 	 * chown can't fail when done as root.
1903 	 */
1904 	if ((vp->v_type == VCHR || vp->v_type == VBLK) &&
1905 	    ((error = suser_xxx(p->p_ucred, p, PRISON_ROOT)) != 0))
1906 		return (error);
1907 
1908 	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
1909 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
1910 	VATTR_NULL(&vattr);
1911 	vattr.va_flags = flags;
1912 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1913 	VOP_UNLOCK(vp, 0, p);
1914 	return (error);
1915 }
1916 
1917 /*
1918  * Change flags of a file given a path name.
1919  */
1920 #ifndef _SYS_SYSPROTO_H_
1921 struct chflags_args {
1922 	char	*path;
1923 	int	flags;
1924 };
1925 #endif
1926 /* ARGSUSED */
1927 int
1928 chflags(p, uap)
1929 	struct proc *p;
1930 	register struct chflags_args /* {
1931 		syscallarg(char *) path;
1932 		syscallarg(int) flags;
1933 	} */ *uap;
1934 {
1935 	int error;
1936 	struct nameidata nd;
1937 
1938 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
1939 	if ((error = namei(&nd)) != 0)
1940 		return (error);
1941 	error = setfflags(p, nd.ni_vp, SCARG(uap, flags));
1942 	vrele(nd.ni_vp);
1943 	return error;
1944 }
1945 
1946 /*
1947  * Change flags of a file given a file descriptor.
1948  */
1949 #ifndef _SYS_SYSPROTO_H_
1950 struct fchflags_args {
1951 	int	fd;
1952 	int	flags;
1953 };
1954 #endif
1955 /* ARGSUSED */
1956 int
1957 fchflags(p, uap)
1958 	struct proc *p;
1959 	register struct fchflags_args /* {
1960 		syscallarg(int) fd;
1961 		syscallarg(int) flags;
1962 	} */ *uap;
1963 {
1964 	struct file *fp;
1965 	int error;
1966 
1967 	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
1968 		return (error);
1969 	return setfflags(p, (struct vnode *) fp->f_data, SCARG(uap, flags));
1970 }
1971 
1972 static int
1973 setfmode(p, vp, mode)
1974 	struct proc *p;
1975 	struct vnode *vp;
1976 	int mode;
1977 {
1978 	int error;
1979 	struct vattr vattr;
1980 
1981 	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
1982 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
1983 	VATTR_NULL(&vattr);
1984 	vattr.va_mode = mode & ALLPERMS;
1985 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1986 	VOP_UNLOCK(vp, 0, p);
1987 	return error;
1988 }
1989 
1990 /*
1991  * Change mode of a file given path name.
1992  */
1993 #ifndef _SYS_SYSPROTO_H_
1994 struct chmod_args {
1995 	char	*path;
1996 	int	mode;
1997 };
1998 #endif
1999 /* ARGSUSED */
2000 int
2001 chmod(p, uap)
2002 	struct proc *p;
2003 	register struct chmod_args /* {
2004 		syscallarg(char *) path;
2005 		syscallarg(int) mode;
2006 	} */ *uap;
2007 {
2008 	int error;
2009 	struct nameidata nd;
2010 
2011 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
2012 	if ((error = namei(&nd)) != 0)
2013 		return (error);
2014 	error = setfmode(p, nd.ni_vp, SCARG(uap, mode));
2015 	vrele(nd.ni_vp);
2016 	return error;
2017 }
2018 
2019 /*
2020  * Change mode of a file given path name (don't follow links.)
2021  */
2022 #ifndef _SYS_SYSPROTO_H_
2023 struct lchmod_args {
2024 	char	*path;
2025 	int	mode;
2026 };
2027 #endif
2028 /* ARGSUSED */
2029 int
2030 lchmod(p, uap)
2031 	struct proc *p;
2032 	register struct lchmod_args /* {
2033 		syscallarg(char *) path;
2034 		syscallarg(int) mode;
2035 	} */ *uap;
2036 {
2037 	int error;
2038 	struct nameidata nd;
2039 
2040 	NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
2041 	if ((error = namei(&nd)) != 0)
2042 		return (error);
2043 	error = setfmode(p, nd.ni_vp, SCARG(uap, mode));
2044 	vrele(nd.ni_vp);
2045 	return error;
2046 }
2047 
2048 /*
2049  * Change mode of a file given a file descriptor.
2050  */
2051 #ifndef _SYS_SYSPROTO_H_
2052 struct fchmod_args {
2053 	int	fd;
2054 	int	mode;
2055 };
2056 #endif
2057 /* ARGSUSED */
2058 int
2059 fchmod(p, uap)
2060 	struct proc *p;
2061 	register struct fchmod_args /* {
2062 		syscallarg(int) fd;
2063 		syscallarg(int) mode;
2064 	} */ *uap;
2065 {
2066 	struct file *fp;
2067 	int error;
2068 
2069 	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
2070 		return (error);
2071 	return setfmode(p, (struct vnode *)fp->f_data, SCARG(uap, mode));
2072 }
2073 
2074 static int
2075 setfown(p, vp, uid, gid)
2076 	struct proc *p;
2077 	struct vnode *vp;
2078 	uid_t uid;
2079 	gid_t gid;
2080 {
2081 	int error;
2082 	struct vattr vattr;
2083 
2084 	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
2085 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
2086 	VATTR_NULL(&vattr);
2087 	vattr.va_uid = uid;
2088 	vattr.va_gid = gid;
2089 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
2090 	VOP_UNLOCK(vp, 0, p);
2091 	return error;
2092 }
2093 
2094 /*
2095  * Set ownership given a path name.
2096  */
2097 #ifndef _SYS_SYSPROTO_H_
2098 struct chown_args {
2099 	char	*path;
2100 	int	uid;
2101 	int	gid;
2102 };
2103 #endif
2104 /* ARGSUSED */
2105 int
2106 chown(p, uap)
2107 	struct proc *p;
2108 	register struct chown_args /* {
2109 		syscallarg(char *) path;
2110 		syscallarg(int) uid;
2111 		syscallarg(int) gid;
2112 	} */ *uap;
2113 {
2114 	int error;
2115 	struct nameidata nd;
2116 
2117 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
2118 	if ((error = namei(&nd)) != 0)
2119 		return (error);
2120 	error = setfown(p, nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid));
2121 	vrele(nd.ni_vp);
2122 
2123 	return (error);
2124 }
2125 
2126 /*
2127  * Set ownership given a path name, do not cross symlinks.
2128  */
2129 #ifndef _SYS_SYSPROTO_H_
2130 struct lchown_args {
2131 	char	*path;
2132 	int	uid;
2133 	int	gid;
2134 };
2135 #endif
2136 /* ARGSUSED */
2137 int
2138 lchown(p, uap)
2139 	struct proc *p;
2140 	register struct lchown_args /* {
2141 		syscallarg(char *) path;
2142 		syscallarg(int) uid;
2143 		syscallarg(int) gid;
2144 	} */ *uap;
2145 {
2146 	int error;
2147 	struct nameidata nd;
2148 
2149 	NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
2150 	if ((error = namei(&nd)) != 0)
2151 		return (error);
2152 	error = setfown(p, nd.ni_vp, SCARG(uap, uid), SCARG(uap, gid));
2153 	vrele(nd.ni_vp);
2154 	return (error);
2155 }
2156 
2157 /*
2158  * Set ownership given a file descriptor.
2159  */
2160 #ifndef _SYS_SYSPROTO_H_
2161 struct fchown_args {
2162 	int	fd;
2163 	int	uid;
2164 	int	gid;
2165 };
2166 #endif
2167 /* ARGSUSED */
2168 int
2169 fchown(p, uap)
2170 	struct proc *p;
2171 	register struct fchown_args /* {
2172 		syscallarg(int) fd;
2173 		syscallarg(int) uid;
2174 		syscallarg(int) gid;
2175 	} */ *uap;
2176 {
2177 	struct file *fp;
2178 	int error;
2179 
2180 	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
2181 		return (error);
2182 	return setfown(p, (struct vnode *)fp->f_data,
2183 		SCARG(uap, uid), SCARG(uap, gid));
2184 }
2185 
2186 static int
2187 getutimes(usrtvp, tsp)
2188 	const struct timeval *usrtvp;
2189 	struct timespec *tsp;
2190 {
2191 	struct timeval tv[2];
2192 	int error;
2193 
2194 	if (usrtvp == NULL) {
2195 		microtime(&tv[0]);
2196 		TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]);
2197 		tsp[1] = tsp[0];
2198 	} else {
2199 		if ((error = copyin(usrtvp, tv, sizeof (tv))) != 0)
2200 			return (error);
2201 		TIMEVAL_TO_TIMESPEC(&tv[0], &tsp[0]);
2202 		TIMEVAL_TO_TIMESPEC(&tv[1], &tsp[1]);
2203 	}
2204 	return 0;
2205 }
2206 
2207 static int
2208 setutimes(p, vp, ts, nullflag)
2209 	struct proc *p;
2210 	struct vnode *vp;
2211 	const struct timespec *ts;
2212 	int nullflag;
2213 {
2214 	int error;
2215 	struct vattr vattr;
2216 
2217 	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
2218 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
2219 	VATTR_NULL(&vattr);
2220 	vattr.va_atime = ts[0];
2221 	vattr.va_mtime = ts[1];
2222 	if (nullflag)
2223 		vattr.va_vaflags |= VA_UTIMES_NULL;
2224 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
2225 	VOP_UNLOCK(vp, 0, p);
2226 	return error;
2227 }
2228 
2229 /*
2230  * Set the access and modification times of a file.
2231  */
2232 #ifndef _SYS_SYSPROTO_H_
2233 struct utimes_args {
2234 	char	*path;
2235 	struct	timeval *tptr;
2236 };
2237 #endif
2238 /* ARGSUSED */
2239 int
2240 utimes(p, uap)
2241 	struct proc *p;
2242 	register struct utimes_args /* {
2243 		syscallarg(char *) path;
2244 		syscallarg(struct timeval *) tptr;
2245 	} */ *uap;
2246 {
2247 	struct timespec ts[2];
2248 	struct timeval *usrtvp;
2249 	int error;
2250 	struct nameidata nd;
2251 
2252 	usrtvp = SCARG(uap, tptr);
2253 	if ((error = getutimes(usrtvp, ts)) != 0)
2254 		return (error);
2255 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
2256 	if ((error = namei(&nd)) != 0)
2257 		return (error);
2258 	error = setutimes(p, nd.ni_vp, ts, usrtvp == NULL);
2259 	vrele(nd.ni_vp);
2260 	return (error);
2261 }
2262 
2263 /*
2264  * Set the access and modification times of a file.
2265  */
2266 #ifndef _SYS_SYSPROTO_H_
2267 struct lutimes_args {
2268 	char	*path;
2269 	struct	timeval *tptr;
2270 };
2271 #endif
2272 /* ARGSUSED */
2273 int
2274 lutimes(p, uap)
2275 	struct proc *p;
2276 	register struct lutimes_args /* {
2277 		syscallarg(char *) path;
2278 		syscallarg(struct timeval *) tptr;
2279 	} */ *uap;
2280 {
2281 	struct timespec ts[2];
2282 	struct timeval *usrtvp;
2283 	int error;
2284 	struct nameidata nd;
2285 
2286 	usrtvp = SCARG(uap, tptr);
2287 	if ((error = getutimes(usrtvp, ts)) != 0)
2288 		return (error);
2289 	NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
2290 	if ((error = namei(&nd)) != 0)
2291 		return (error);
2292 	error = setutimes(p, nd.ni_vp, ts, usrtvp == NULL);
2293 	vrele(nd.ni_vp);
2294 	return (error);
2295 }
2296 
2297 /*
2298  * Set the access and modification times of a file.
2299  */
2300 #ifndef _SYS_SYSPROTO_H_
2301 struct futimes_args {
2302 	int	fd;
2303 	struct	timeval *tptr;
2304 };
2305 #endif
2306 /* ARGSUSED */
2307 int
2308 futimes(p, uap)
2309 	struct proc *p;
2310 	register struct futimes_args /* {
2311 		syscallarg(int ) fd;
2312 		syscallarg(struct timeval *) tptr;
2313 	} */ *uap;
2314 {
2315 	struct timespec ts[2];
2316 	struct file *fp;
2317 	struct timeval *usrtvp;
2318 	int error;
2319 
2320 	usrtvp = SCARG(uap, tptr);
2321 	if ((error = getutimes(usrtvp, ts)) != 0)
2322 		return (error);
2323 	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
2324 		return (error);
2325 	return setutimes(p, (struct vnode *)fp->f_data, ts, usrtvp == NULL);
2326 }
2327 
2328 /*
2329  * Truncate a file given its path name.
2330  */
2331 #ifndef _SYS_SYSPROTO_H_
2332 struct truncate_args {
2333 	char	*path;
2334 	int	pad;
2335 	off_t	length;
2336 };
2337 #endif
2338 /* ARGSUSED */
2339 int
2340 truncate(p, uap)
2341 	struct proc *p;
2342 	register struct truncate_args /* {
2343 		syscallarg(char *) path;
2344 		syscallarg(int) pad;
2345 		syscallarg(off_t) length;
2346 	} */ *uap;
2347 {
2348 	register struct vnode *vp;
2349 	struct vattr vattr;
2350 	int error;
2351 	struct nameidata nd;
2352 
2353 	if (uap->length < 0)
2354 		return(EINVAL);
2355 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
2356 	if ((error = namei(&nd)) != 0)
2357 		return (error);
2358 	vp = nd.ni_vp;
2359 	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
2360 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
2361 	if (vp->v_type == VDIR)
2362 		error = EISDIR;
2363 	else if ((error = vn_writechk(vp)) == 0 &&
2364 	    (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, p)) == 0) {
2365 		VATTR_NULL(&vattr);
2366 		vattr.va_size = SCARG(uap, length);
2367 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
2368 	}
2369 	vput(vp);
2370 	return (error);
2371 }
2372 
2373 /*
2374  * Truncate a file given a file descriptor.
2375  */
2376 #ifndef _SYS_SYSPROTO_H_
2377 struct ftruncate_args {
2378 	int	fd;
2379 	int	pad;
2380 	off_t	length;
2381 };
2382 #endif
2383 /* ARGSUSED */
2384 int
2385 ftruncate(p, uap)
2386 	struct proc *p;
2387 	register struct ftruncate_args /* {
2388 		syscallarg(int) fd;
2389 		syscallarg(int) pad;
2390 		syscallarg(off_t) length;
2391 	} */ *uap;
2392 {
2393 	struct vattr vattr;
2394 	struct vnode *vp;
2395 	struct file *fp;
2396 	int error;
2397 
2398 	if (uap->length < 0)
2399 		return(EINVAL);
2400 	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
2401 		return (error);
2402 	if ((fp->f_flag & FWRITE) == 0)
2403 		return (EINVAL);
2404 	vp = (struct vnode *)fp->f_data;
2405 	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
2406 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
2407 	if (vp->v_type == VDIR)
2408 		error = EISDIR;
2409 	else if ((error = vn_writechk(vp)) == 0) {
2410 		VATTR_NULL(&vattr);
2411 		vattr.va_size = SCARG(uap, length);
2412 		error = VOP_SETATTR(vp, &vattr, fp->f_cred, p);
2413 	}
2414 	VOP_UNLOCK(vp, 0, p);
2415 	return (error);
2416 }
2417 
2418 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
2419 /*
2420  * Truncate a file given its path name.
2421  */
2422 #ifndef _SYS_SYSPROTO_H_
2423 struct otruncate_args {
2424 	char	*path;
2425 	long	length;
2426 };
2427 #endif
2428 /* ARGSUSED */
2429 int
2430 otruncate(p, uap)
2431 	struct proc *p;
2432 	register struct otruncate_args /* {
2433 		syscallarg(char *) path;
2434 		syscallarg(long) length;
2435 	} */ *uap;
2436 {
2437 	struct truncate_args /* {
2438 		syscallarg(char *) path;
2439 		syscallarg(int) pad;
2440 		syscallarg(off_t) length;
2441 	} */ nuap;
2442 
2443 	SCARG(&nuap, path) = SCARG(uap, path);
2444 	SCARG(&nuap, length) = SCARG(uap, length);
2445 	return (truncate(p, &nuap));
2446 }
2447 
2448 /*
2449  * Truncate a file given a file descriptor.
2450  */
2451 #ifndef _SYS_SYSPROTO_H_
2452 struct oftruncate_args {
2453 	int	fd;
2454 	long	length;
2455 };
2456 #endif
2457 /* ARGSUSED */
2458 int
2459 oftruncate(p, uap)
2460 	struct proc *p;
2461 	register struct oftruncate_args /* {
2462 		syscallarg(int) fd;
2463 		syscallarg(long) length;
2464 	} */ *uap;
2465 {
2466 	struct ftruncate_args /* {
2467 		syscallarg(int) fd;
2468 		syscallarg(int) pad;
2469 		syscallarg(off_t) length;
2470 	} */ nuap;
2471 
2472 	SCARG(&nuap, fd) = SCARG(uap, fd);
2473 	SCARG(&nuap, length) = SCARG(uap, length);
2474 	return (ftruncate(p, &nuap));
2475 }
2476 #endif /* COMPAT_43 || COMPAT_SUNOS */
2477 
2478 /*
2479  * Sync an open file.
2480  */
2481 #ifndef _SYS_SYSPROTO_H_
2482 struct fsync_args {
2483 	int	fd;
2484 };
2485 #endif
2486 /* ARGSUSED */
2487 int
2488 fsync(p, uap)
2489 	struct proc *p;
2490 	struct fsync_args /* {
2491 		syscallarg(int) fd;
2492 	} */ *uap;
2493 {
2494 	register struct vnode *vp;
2495 	struct file *fp;
2496 	int error;
2497 
2498 	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
2499 		return (error);
2500 	vp = (struct vnode *)fp->f_data;
2501 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
2502 	if (vp->v_object)
2503 		vm_object_page_clean(vp->v_object, 0, 0, 0);
2504 	if ((error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p)) == 0 &&
2505 	    vp->v_mount && (vp->v_mount->mnt_flag & MNT_SOFTDEP) &&
2506 	    bioops.io_fsync)
2507 		error = (*bioops.io_fsync)(vp);
2508 	VOP_UNLOCK(vp, 0, p);
2509 	return (error);
2510 }
2511 
2512 /*
2513  * Rename files.  Source and destination must either both be directories,
2514  * or both not be directories.  If target is a directory, it must be empty.
2515  */
2516 #ifndef _SYS_SYSPROTO_H_
2517 struct rename_args {
2518 	char	*from;
2519 	char	*to;
2520 };
2521 #endif
2522 /* ARGSUSED */
2523 int
2524 rename(p, uap)
2525 	struct proc *p;
2526 	register struct rename_args /* {
2527 		syscallarg(char *) from;
2528 		syscallarg(char *) to;
2529 	} */ *uap;
2530 {
2531 	register struct vnode *tvp, *fvp, *tdvp;
2532 	struct nameidata fromnd, tond;
2533 	int error;
2534 
2535 	NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE,
2536 	    SCARG(uap, from), p);
2537 	if ((error = namei(&fromnd)) != 0)
2538 		return (error);
2539 	fvp = fromnd.ni_vp;
2540 	NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | NOOBJ,
2541 	    UIO_USERSPACE, SCARG(uap, to), p);
2542 	if (fromnd.ni_vp->v_type == VDIR)
2543 		tond.ni_cnd.cn_flags |= WILLBEDIR;
2544 	if ((error = namei(&tond)) != 0) {
2545 		/* Translate error code for rename("dir1", "dir2/."). */
2546 		if (error == EISDIR && fvp->v_type == VDIR)
2547 			error = EINVAL;
2548 		VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
2549 		vrele(fromnd.ni_dvp);
2550 		vrele(fvp);
2551 		goto out1;
2552 	}
2553 	tdvp = tond.ni_dvp;
2554 	tvp = tond.ni_vp;
2555 	if (tvp != NULL) {
2556 		if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
2557 			error = ENOTDIR;
2558 			goto out;
2559 		} else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
2560 			error = EISDIR;
2561 			goto out;
2562 		}
2563 	}
2564 	if (fvp == tdvp)
2565 		error = EINVAL;
2566 	/*
2567 	 * If source is the same as the destination (that is the
2568 	 * same inode number with the same name in the same directory),
2569 	 * then there is nothing to do.
2570 	 */
2571 	if (fvp == tvp && fromnd.ni_dvp == tdvp &&
2572 	    fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen &&
2573 	    !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr,
2574 	      fromnd.ni_cnd.cn_namelen))
2575 		error = -1;
2576 out:
2577 	if (!error) {
2578 		VOP_LEASE(tdvp, p, p->p_ucred, LEASE_WRITE);
2579 		if (fromnd.ni_dvp != tdvp) {
2580 			VOP_LEASE(fromnd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
2581 		}
2582 		if (tvp) {
2583 			VOP_LEASE(tvp, p, p->p_ucred, LEASE_WRITE);
2584 		}
2585 		error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
2586 				   tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
2587 	} else {
2588 		VOP_ABORTOP(tond.ni_dvp, &tond.ni_cnd);
2589 		if (tdvp == tvp)
2590 			vrele(tdvp);
2591 		else
2592 			vput(tdvp);
2593 		if (tvp)
2594 			vput(tvp);
2595 		VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
2596 		vrele(fromnd.ni_dvp);
2597 		vrele(fvp);
2598 	}
2599 	vrele(tond.ni_startdir);
2600 	ASSERT_VOP_UNLOCKED(fromnd.ni_dvp, "rename");
2601 	ASSERT_VOP_UNLOCKED(fromnd.ni_vp, "rename");
2602 	ASSERT_VOP_UNLOCKED(tond.ni_dvp, "rename");
2603 	ASSERT_VOP_UNLOCKED(tond.ni_vp, "rename");
2604 	zfree(namei_zone, tond.ni_cnd.cn_pnbuf);
2605 out1:
2606 	if (fromnd.ni_startdir)
2607 		vrele(fromnd.ni_startdir);
2608 	zfree(namei_zone, fromnd.ni_cnd.cn_pnbuf);
2609 	if (error == -1)
2610 		return (0);
2611 	return (error);
2612 }
2613 
2614 /*
2615  * Make a directory file.
2616  */
2617 #ifndef _SYS_SYSPROTO_H_
2618 struct mkdir_args {
2619 	char	*path;
2620 	int	mode;
2621 };
2622 #endif
2623 /* ARGSUSED */
2624 int
2625 mkdir(p, uap)
2626 	struct proc *p;
2627 	register struct mkdir_args /* {
2628 		syscallarg(char *) path;
2629 		syscallarg(int) mode;
2630 	} */ *uap;
2631 {
2632 	register struct vnode *vp;
2633 	struct vattr vattr;
2634 	int error;
2635 	struct nameidata nd;
2636 
2637 	NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, SCARG(uap, path), p);
2638 	nd.ni_cnd.cn_flags |= WILLBEDIR;
2639 	if ((error = namei(&nd)) != 0)
2640 		return (error);
2641 	vp = nd.ni_vp;
2642 	if (vp != NULL) {
2643 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
2644 		if (nd.ni_dvp == vp)
2645 			vrele(nd.ni_dvp);
2646 		else
2647 			vput(nd.ni_dvp);
2648 		vrele(vp);
2649 		return (EEXIST);
2650 	}
2651 	VATTR_NULL(&vattr);
2652 	vattr.va_type = VDIR;
2653 	vattr.va_mode = (SCARG(uap, mode) & ACCESSPERMS) &~ p->p_fd->fd_cmask;
2654 	VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
2655 	error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
2656 	vput(nd.ni_dvp);
2657 	if (!error)
2658 		vput(nd.ni_vp);
2659 	ASSERT_VOP_UNLOCKED(nd.ni_dvp, "mkdir");
2660 	ASSERT_VOP_UNLOCKED(nd.ni_vp, "mkdir");
2661 	return (error);
2662 }
2663 
2664 /*
2665  * Remove a directory file.
2666  */
2667 #ifndef _SYS_SYSPROTO_H_
2668 struct rmdir_args {
2669 	char	*path;
2670 };
2671 #endif
2672 /* ARGSUSED */
2673 int
2674 rmdir(p, uap)
2675 	struct proc *p;
2676 	struct rmdir_args /* {
2677 		syscallarg(char *) path;
2678 	} */ *uap;
2679 {
2680 	register struct vnode *vp;
2681 	int error;
2682 	struct nameidata nd;
2683 
2684 	NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE,
2685 	    SCARG(uap, path), p);
2686 	if ((error = namei(&nd)) != 0)
2687 		return (error);
2688 	vp = nd.ni_vp;
2689 	if (vp->v_type != VDIR) {
2690 		error = ENOTDIR;
2691 		goto out;
2692 	}
2693 	/*
2694 	 * No rmdir "." please.
2695 	 */
2696 	if (nd.ni_dvp == vp) {
2697 		error = EINVAL;
2698 		goto out;
2699 	}
2700 	/*
2701 	 * The root of a mounted filesystem cannot be deleted.
2702 	 */
2703 	if (vp->v_flag & VROOT)
2704 		error = EBUSY;
2705 out:
2706 	if (!error) {
2707 		VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
2708 		VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
2709 		error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
2710 	} else {
2711 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
2712 	}
2713 	if (nd.ni_dvp == vp)
2714 		vrele(nd.ni_dvp);
2715 	else
2716 		vput(nd.ni_dvp);
2717 	if (vp != NULLVP)
2718 		vput(vp);
2719 	ASSERT_VOP_UNLOCKED(nd.ni_dvp, "rmdir");
2720 	ASSERT_VOP_UNLOCKED(nd.ni_vp, "rmdir");
2721 	return (error);
2722 }
2723 
2724 #ifdef COMPAT_43
2725 /*
2726  * Read a block of directory entries in a file system independent format.
2727  */
2728 #ifndef _SYS_SYSPROTO_H_
2729 struct ogetdirentries_args {
2730 	int	fd;
2731 	char	*buf;
2732 	u_int	count;
2733 	long	*basep;
2734 };
2735 #endif
2736 int
2737 ogetdirentries(p, uap)
2738 	struct proc *p;
2739 	register struct ogetdirentries_args /* {
2740 		syscallarg(int) fd;
2741 		syscallarg(char *) buf;
2742 		syscallarg(u_int) count;
2743 		syscallarg(long *) basep;
2744 	} */ *uap;
2745 {
2746 	struct vnode *vp;
2747 	struct file *fp;
2748 	struct uio auio, kuio;
2749 	struct iovec aiov, kiov;
2750 	struct dirent *dp, *edp;
2751 	caddr_t dirbuf;
2752 	int error, eofflag, readcnt;
2753 	long loff;
2754 
2755 	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
2756 		return (error);
2757 	if ((fp->f_flag & FREAD) == 0)
2758 		return (EBADF);
2759 	vp = (struct vnode *)fp->f_data;
2760 unionread:
2761 	if (vp->v_type != VDIR)
2762 		return (EINVAL);
2763 	aiov.iov_base = SCARG(uap, buf);
2764 	aiov.iov_len = SCARG(uap, count);
2765 	auio.uio_iov = &aiov;
2766 	auio.uio_iovcnt = 1;
2767 	auio.uio_rw = UIO_READ;
2768 	auio.uio_segflg = UIO_USERSPACE;
2769 	auio.uio_procp = p;
2770 	auio.uio_resid = SCARG(uap, count);
2771 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
2772 	loff = auio.uio_offset = fp->f_offset;
2773 #	if (BYTE_ORDER != LITTLE_ENDIAN)
2774 		if (vp->v_mount->mnt_maxsymlinklen <= 0) {
2775 			error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
2776 			    NULL, NULL);
2777 			fp->f_offset = auio.uio_offset;
2778 		} else
2779 #	endif
2780 	{
2781 		kuio = auio;
2782 		kuio.uio_iov = &kiov;
2783 		kuio.uio_segflg = UIO_SYSSPACE;
2784 		kiov.iov_len = SCARG(uap, count);
2785 		MALLOC(dirbuf, caddr_t, SCARG(uap, count), M_TEMP, M_WAITOK);
2786 		kiov.iov_base = dirbuf;
2787 		error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag,
2788 			    NULL, NULL);
2789 		fp->f_offset = kuio.uio_offset;
2790 		if (error == 0) {
2791 			readcnt = SCARG(uap, count) - kuio.uio_resid;
2792 			edp = (struct dirent *)&dirbuf[readcnt];
2793 			for (dp = (struct dirent *)dirbuf; dp < edp; ) {
2794 #				if (BYTE_ORDER == LITTLE_ENDIAN)
2795 					/*
2796 					 * The expected low byte of
2797 					 * dp->d_namlen is our dp->d_type.
2798 					 * The high MBZ byte of dp->d_namlen
2799 					 * is our dp->d_namlen.
2800 					 */
2801 					dp->d_type = dp->d_namlen;
2802 					dp->d_namlen = 0;
2803 #				else
2804 					/*
2805 					 * The dp->d_type is the high byte
2806 					 * of the expected dp->d_namlen,
2807 					 * so must be zero'ed.
2808 					 */
2809 					dp->d_type = 0;
2810 #				endif
2811 				if (dp->d_reclen > 0) {
2812 					dp = (struct dirent *)
2813 					    ((char *)dp + dp->d_reclen);
2814 				} else {
2815 					error = EIO;
2816 					break;
2817 				}
2818 			}
2819 			if (dp >= edp)
2820 				error = uiomove(dirbuf, readcnt, &auio);
2821 		}
2822 		FREE(dirbuf, M_TEMP);
2823 	}
2824 	VOP_UNLOCK(vp, 0, p);
2825 	if (error)
2826 		return (error);
2827 	if (SCARG(uap, count) == auio.uio_resid) {
2828 		if (union_dircheckp) {
2829 			error = union_dircheckp(p, &vp, fp);
2830 			if (error == -1)
2831 				goto unionread;
2832 			if (error)
2833 				return (error);
2834 		}
2835 		if ((vp->v_flag & VROOT) &&
2836 		    (vp->v_mount->mnt_flag & MNT_UNION)) {
2837 			struct vnode *tvp = vp;
2838 			vp = vp->v_mount->mnt_vnodecovered;
2839 			VREF(vp);
2840 			fp->f_data = (caddr_t) vp;
2841 			fp->f_offset = 0;
2842 			vrele(tvp);
2843 			goto unionread;
2844 		}
2845 	}
2846 	error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
2847 	    sizeof(long));
2848 	p->p_retval[0] = SCARG(uap, count) - auio.uio_resid;
2849 	return (error);
2850 }
2851 #endif /* COMPAT_43 */
2852 
2853 /*
2854  * Read a block of directory entries in a file system independent format.
2855  */
2856 #ifndef _SYS_SYSPROTO_H_
2857 struct getdirentries_args {
2858 	int	fd;
2859 	char	*buf;
2860 	u_int	count;
2861 	long	*basep;
2862 };
2863 #endif
2864 int
2865 getdirentries(p, uap)
2866 	struct proc *p;
2867 	register struct getdirentries_args /* {
2868 		syscallarg(int) fd;
2869 		syscallarg(char *) buf;
2870 		syscallarg(u_int) count;
2871 		syscallarg(long *) basep;
2872 	} */ *uap;
2873 {
2874 	struct vnode *vp;
2875 	struct file *fp;
2876 	struct uio auio;
2877 	struct iovec aiov;
2878 	long loff;
2879 	int error, eofflag;
2880 
2881 	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
2882 		return (error);
2883 	if ((fp->f_flag & FREAD) == 0)
2884 		return (EBADF);
2885 	vp = (struct vnode *)fp->f_data;
2886 unionread:
2887 	if (vp->v_type != VDIR)
2888 		return (EINVAL);
2889 	aiov.iov_base = SCARG(uap, buf);
2890 	aiov.iov_len = SCARG(uap, count);
2891 	auio.uio_iov = &aiov;
2892 	auio.uio_iovcnt = 1;
2893 	auio.uio_rw = UIO_READ;
2894 	auio.uio_segflg = UIO_USERSPACE;
2895 	auio.uio_procp = p;
2896 	auio.uio_resid = SCARG(uap, count);
2897 	/* vn_lock(vp, LK_SHARED | LK_RETRY, p); */
2898 	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
2899 	loff = auio.uio_offset = fp->f_offset;
2900 	error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, NULL, NULL);
2901 	fp->f_offset = auio.uio_offset;
2902 	VOP_UNLOCK(vp, 0, p);
2903 	if (error)
2904 		return (error);
2905 	if (SCARG(uap, count) == auio.uio_resid) {
2906 		if (union_dircheckp) {
2907 			error = union_dircheckp(p, &vp, fp);
2908 			if (error == -1)
2909 				goto unionread;
2910 			if (error)
2911 				return (error);
2912 		}
2913 		if ((vp->v_flag & VROOT) &&
2914 		    (vp->v_mount->mnt_flag & MNT_UNION)) {
2915 			struct vnode *tvp = vp;
2916 			vp = vp->v_mount->mnt_vnodecovered;
2917 			VREF(vp);
2918 			fp->f_data = (caddr_t) vp;
2919 			fp->f_offset = 0;
2920 			vrele(tvp);
2921 			goto unionread;
2922 		}
2923 	}
2924 	if (SCARG(uap, basep) != NULL) {
2925 		error = copyout((caddr_t)&loff, (caddr_t)SCARG(uap, basep),
2926 		    sizeof(long));
2927 	}
2928 	p->p_retval[0] = SCARG(uap, count) - auio.uio_resid;
2929 	return (error);
2930 }
2931 #ifndef _SYS_SYSPROTO_H_
2932 struct getdents_args {
2933 	int fd;
2934 	char *buf;
2935 	size_t count;
2936 };
2937 #endif
2938 int
2939 getdents(p, uap)
2940 	struct proc *p;
2941 	register struct getdents_args /* {
2942 		syscallarg(int) fd;
2943 		syscallarg(char *) buf;
2944 		syscallarg(u_int) count;
2945 	} */ *uap;
2946 {
2947 	struct getdirentries_args ap;
2948 	ap.fd = uap->fd;
2949 	ap.buf = uap->buf;
2950 	ap.count = uap->count;
2951 	ap.basep = NULL;
2952 	return getdirentries(p, &ap);
2953 }
2954 
2955 /*
2956  * Set the mode mask for creation of filesystem nodes.
2957  */
2958 #ifndef _SYS_SYSPROTO_H_
2959 struct umask_args {
2960 	int	newmask;
2961 };
2962 #endif
2963 int
2964 umask(p, uap)
2965 	struct proc *p;
2966 	struct umask_args /* {
2967 		syscallarg(int) newmask;
2968 	} */ *uap;
2969 {
2970 	register struct filedesc *fdp;
2971 
2972 	fdp = p->p_fd;
2973 	p->p_retval[0] = fdp->fd_cmask;
2974 	fdp->fd_cmask = SCARG(uap, newmask) & ALLPERMS;
2975 	return (0);
2976 }
2977 
2978 /*
2979  * Void all references to file by ripping underlying filesystem
2980  * away from vnode.
2981  */
2982 #ifndef _SYS_SYSPROTO_H_
2983 struct revoke_args {
2984 	char	*path;
2985 };
2986 #endif
2987 /* ARGSUSED */
2988 int
2989 revoke(p, uap)
2990 	struct proc *p;
2991 	register struct revoke_args /* {
2992 		syscallarg(char *) path;
2993 	} */ *uap;
2994 {
2995 	register struct vnode *vp;
2996 	struct vattr vattr;
2997 	int error;
2998 	struct nameidata nd;
2999 
3000 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
3001 	if ((error = namei(&nd)) != 0)
3002 		return (error);
3003 	vp = nd.ni_vp;
3004 	if (vp->v_type != VCHR && vp->v_type != VBLK) {
3005 		error = EINVAL;
3006 		goto out;
3007 	}
3008 	if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) != 0)
3009 		goto out;
3010 	if (p->p_ucred->cr_uid != vattr.va_uid &&
3011 	    (error = suser_xxx(0, p, PRISON_ROOT)))
3012 		goto out;
3013 	if (vcount(vp) > 1)
3014 		VOP_REVOKE(vp, REVOKEALL);
3015 out:
3016 	vrele(vp);
3017 	return (error);
3018 }
3019 
3020 /*
3021  * Convert a user file descriptor to a kernel file entry.
3022  */
3023 int
3024 getvnode(fdp, fd, fpp)
3025 	struct filedesc *fdp;
3026 	int fd;
3027 	struct file **fpp;
3028 {
3029 	struct file *fp;
3030 
3031 	if ((u_int)fd >= fdp->fd_nfiles ||
3032 	    (fp = fdp->fd_ofiles[fd]) == NULL)
3033 		return (EBADF);
3034 	if (fp->f_type != DTYPE_VNODE && fp->f_type != DTYPE_FIFO)
3035 		return (EINVAL);
3036 	*fpp = fp;
3037 	return (0);
3038 }
3039 #ifndef _SYS_SYSPROTO_H_
3040 struct  __getcwd_args {
3041 	u_char	*buf;
3042 	u_int	buflen;
3043 };
3044 #endif
3045 
3046 SYSCTL_DECL(_vfs_cache);
3047 #define STATNODE(mode, name, var) \
3048 	SYSCTL_INT(_vfs_cache, OID_AUTO, name, mode, var, 0, "");
3049 
3050 static int disablecwd;
3051 SYSCTL_INT(_debug, OID_AUTO, disablecwd, CTLFLAG_RW, &disablecwd, 0, "");
3052 
3053 static u_long numcwdcalls; STATNODE(CTLFLAG_RD, numcwdcalls, &numcwdcalls);
3054 static u_long numcwdfail1; STATNODE(CTLFLAG_RD, numcwdfail1, &numcwdfail1);
3055 static u_long numcwdfail2; STATNODE(CTLFLAG_RD, numcwdfail2, &numcwdfail2);
3056 static u_long numcwdfail3; STATNODE(CTLFLAG_RD, numcwdfail3, &numcwdfail3);
3057 static u_long numcwdfail4; STATNODE(CTLFLAG_RD, numcwdfail4, &numcwdfail4);
3058 static u_long numcwdfound; STATNODE(CTLFLAG_RD, numcwdfound, &numcwdfound);
3059 int
3060 __getcwd(p, uap)
3061 	struct proc *p;
3062 	struct __getcwd_args *uap;
3063 {
3064 	char *bp, *buf;
3065 	int error, i, slash_prefixed;
3066 	struct filedesc *fdp;
3067 	struct namecache *ncp;
3068 	struct vnode *vp;
3069 
3070 	numcwdcalls++;
3071 	if (disablecwd)
3072 		return (ENODEV);
3073 	if (uap->buflen < 2)
3074 		return (EINVAL);
3075 	if (uap->buflen > MAXPATHLEN)
3076 		uap->buflen = MAXPATHLEN;
3077 	buf = bp = malloc(uap->buflen, M_TEMP, M_WAITOK);
3078 	bp += uap->buflen - 1;
3079 	*bp = '\0';
3080 	fdp = p->p_fd;
3081 	slash_prefixed = 0;
3082 	for (vp = fdp->fd_cdir; vp != fdp->fd_rdir && vp != rootvnode;) {
3083 		if (vp->v_flag & VROOT) {
3084 			vp = vp->v_mount->mnt_vnodecovered;
3085 			continue;
3086 		}
3087 		if (vp->v_dd->v_id != vp->v_ddid) {
3088 			numcwdfail1++;
3089 			free(buf, M_TEMP);
3090 			return (ENOTDIR);
3091 		}
3092 		ncp = TAILQ_FIRST(&vp->v_cache_dst);
3093 		if (!ncp) {
3094 			numcwdfail2++;
3095 			free(buf, M_TEMP);
3096 			return (ENOENT);
3097 		}
3098 		if (ncp->nc_dvp != vp->v_dd) {
3099 			numcwdfail3++;
3100 			free(buf, M_TEMP);
3101 			return (EBADF);
3102 		}
3103 		for (i = ncp->nc_nlen - 1; i >= 0; i--) {
3104 			if (bp == buf) {
3105 				numcwdfail4++;
3106 				free(buf, M_TEMP);
3107 				return (ENOMEM);
3108 			}
3109 			*--bp = ncp->nc_name[i];
3110 		}
3111 		if (bp == buf) {
3112 			numcwdfail4++;
3113 			free(buf, M_TEMP);
3114 			return (ENOMEM);
3115 		}
3116 		*--bp = '/';
3117 		slash_prefixed = 1;
3118 		vp = vp->v_dd;
3119 	}
3120 	if (!slash_prefixed) {
3121 		if (bp == buf) {
3122 			numcwdfail4++;
3123 			free(buf, M_TEMP);
3124 			return (ENOMEM);
3125 		}
3126 		*--bp = '/';
3127 	}
3128 	numcwdfound++;
3129 	error = copyout(bp, uap->buf, strlen(bp) + 1);
3130 	free(buf, M_TEMP);
3131 	return (error);
3132 }
3133