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