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