xref: /csrg-svn/sys/kern/vfs_syscalls.c (revision 65859)
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  * %sccs.include.redist.c%
11  *
12  *	@(#)vfs_syscalls.c	8.8 (Berkeley) 01/24/94
13  */
14 
15 #include <sys/param.h>
16 #include <sys/systm.h>
17 #include <sys/namei.h>
18 #include <sys/filedesc.h>
19 #include <sys/kernel.h>
20 #include <sys/file.h>
21 #include <sys/stat.h>
22 #include <sys/vnode.h>
23 #include <sys/mount.h>
24 #include <sys/proc.h>
25 #include <sys/uio.h>
26 #include <sys/malloc.h>
27 #include <sys/dirent.h>
28 
29 #include <vm/vm.h>
30 #include <sys/sysctl.h>
31 
32 static int change_dir __P((struct nameidata *ndp, struct proc *p));
33 
34 /*
35  * Virtual File System System Calls
36  */
37 
38 /*
39  * Mount a file system.
40  */
41 struct mount_args {
42 	int	type;
43 	char	*path;
44 	int	flags;
45 	caddr_t	data;
46 };
47 /* ARGSUSED */
48 mount(p, uap, retval)
49 	struct proc *p;
50 	register struct mount_args *uap;
51 	int *retval;
52 {
53 	register struct vnode *vp;
54 	register struct mount *mp;
55 	int error, flag;
56 	struct nameidata nd;
57 
58 	/*
59 	 * Must be super user
60 	 */
61 	if (error = suser(p->p_ucred, &p->p_acflag))
62 		return (error);
63 	/*
64 	 * Get vnode to be covered
65 	 */
66 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
67 	if (error = namei(&nd))
68 		return (error);
69 	vp = nd.ni_vp;
70 	if (uap->flags & MNT_UPDATE) {
71 		if ((vp->v_flag & VROOT) == 0) {
72 			vput(vp);
73 			return (EINVAL);
74 		}
75 		mp = vp->v_mount;
76 		flag = mp->mnt_flag;
77 		/*
78 		 * We only allow the filesystem to be reloaded if it
79 		 * is currently mounted read-only.
80 		 */
81 		if ((uap->flags & MNT_RELOAD) &&
82 		    ((mp->mnt_flag & MNT_RDONLY) == 0)) {
83 			vput(vp);
84 			return (EOPNOTSUPP);	/* Needs translation */
85 		}
86 		mp->mnt_flag |=
87 		    uap->flags & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE);
88 		VOP_UNLOCK(vp);
89 		goto update;
90 	}
91 	if (vp->v_usecount != 1 && (uap->flags & MNT_UNION) == 0) {
92 		vput(vp);
93 		return (EBUSY);
94 	}
95 	if (error = vinvalbuf(vp, V_SAVE, p->p_ucred, p, 0, 0))
96 		return (error);
97 	if (vp->v_type != VDIR) {
98 		vput(vp);
99 		return (ENOTDIR);
100 	}
101 	if ((u_long)uap->type > MOUNT_MAXTYPE || vfssw[uap->type] == NULL) {
102 		vput(vp);
103 		return (ENODEV);
104 	}
105 
106 	/*
107 	 * Allocate and initialize the file system.
108 	 */
109 	mp = (struct mount *)malloc((u_long)sizeof(struct mount),
110 		M_MOUNT, M_WAITOK);
111 	bzero((char *)mp, (u_long)sizeof(struct mount));
112 	mp->mnt_op = vfssw[uap->type];
113 	if (error = vfs_lock(mp)) {
114 		free((caddr_t)mp, M_MOUNT);
115 		vput(vp);
116 		return (error);
117 	}
118 	if (vp->v_mountedhere != NULL) {
119 		vfs_unlock(mp);
120 		free((caddr_t)mp, M_MOUNT);
121 		vput(vp);
122 		return (EBUSY);
123 	}
124 	vp->v_mountedhere = mp;
125 	mp->mnt_vnodecovered = vp;
126 update:
127 	/*
128 	 * Set the mount level flags.
129 	 */
130 	if (uap->flags & MNT_RDONLY)
131 		mp->mnt_flag |= MNT_RDONLY;
132 	else if (mp->mnt_flag & MNT_RDONLY)
133 		mp->mnt_flag |= MNT_WANTRDWR;
134 	mp->mnt_flag &=~ (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
135 	    MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC);
136 	mp->mnt_flag |= uap->flags & (MNT_NOSUID | MNT_NOEXEC | MNT_NODEV |
137 	    MNT_SYNCHRONOUS | MNT_UNION | MNT_ASYNC);
138 	/*
139 	 * Mount the filesystem.
140 	 */
141 	error = VFS_MOUNT(mp, uap->path, uap->data, &nd, p);
142 	if (mp->mnt_flag & MNT_UPDATE) {
143 		vrele(vp);
144 		if (mp->mnt_flag & MNT_WANTRDWR)
145 			mp->mnt_flag &= ~MNT_RDONLY;
146 		mp->mnt_flag &=~
147 		    (MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_WANTRDWR);
148 		if (error)
149 			mp->mnt_flag = flag;
150 		return (error);
151 	}
152 	/*
153 	 * Put the new filesystem on the mount list after root.
154 	 */
155 	cache_purge(vp);
156 	if (!error) {
157 		TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
158 		VOP_UNLOCK(vp);
159 		vfs_unlock(mp);
160 		error = VFS_START(mp, 0, p);
161 	} else {
162 		mp->mnt_vnodecovered->v_mountedhere = (struct mount *)0;
163 		vfs_unlock(mp);
164 		free((caddr_t)mp, M_MOUNT);
165 		vput(vp);
166 	}
167 	return (error);
168 }
169 
170 /*
171  * Unmount a file system.
172  *
173  * Note: unmount takes a path to the vnode mounted on as argument,
174  * not special file (as before).
175  */
176 struct unmount_args {
177 	char	*path;
178 	int	flags;
179 };
180 /* ARGSUSED */
181 unmount(p, uap, retval)
182 	struct proc *p;
183 	register struct unmount_args *uap;
184 	int *retval;
185 {
186 	register struct vnode *vp;
187 	struct mount *mp;
188 	int error;
189 	struct nameidata nd;
190 
191 	/*
192 	 * Must be super user
193 	 */
194 	if (error = suser(p->p_ucred, &p->p_acflag))
195 		return (error);
196 
197 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
198 	if (error = namei(&nd))
199 		return (error);
200 	vp = nd.ni_vp;
201 	/*
202 	 * Must be the root of the filesystem
203 	 */
204 	if ((vp->v_flag & VROOT) == 0) {
205 		vput(vp);
206 		return (EINVAL);
207 	}
208 	mp = vp->v_mount;
209 	vput(vp);
210 	return (dounmount(mp, uap->flags, p));
211 }
212 
213 /*
214  * Do the actual file system unmount.
215  */
216 dounmount(mp, flags, p)
217 	register struct mount *mp;
218 	int flags;
219 	struct proc *p;
220 {
221 	struct vnode *coveredvp;
222 	int error;
223 
224 	coveredvp = mp->mnt_vnodecovered;
225 	if (vfs_busy(mp))
226 		return (EBUSY);
227 	mp->mnt_flag |= MNT_UNMOUNT;
228 	if (error = vfs_lock(mp))
229 		return (error);
230 
231 	mp->mnt_flag &=~ MNT_ASYNC;
232 	vnode_pager_umount(mp);	/* release cached vnodes */
233 	cache_purgevfs(mp);	/* remove cache entries for this file sys */
234 	if ((error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p)) == 0 ||
235 	    (flags & MNT_FORCE))
236 		error = VFS_UNMOUNT(mp, flags, p);
237 	mp->mnt_flag &= ~MNT_UNMOUNT;
238 	vfs_unbusy(mp);
239 	if (error) {
240 		vfs_unlock(mp);
241 	} else {
242 		vrele(coveredvp);
243 		TAILQ_REMOVE(&mountlist, mp, mnt_list);
244 		mp->mnt_vnodecovered->v_mountedhere = (struct mount *)0;
245 		vfs_unlock(mp);
246 		if (mp->mnt_vnodelist.lh_first != NULL)
247 			panic("unmount: dangling vnode");
248 		free((caddr_t)mp, M_MOUNT);
249 	}
250 	return (error);
251 }
252 
253 /*
254  * Sync each mounted filesystem.
255  */
256 #ifdef DIAGNOSTIC
257 int syncprt = 0;
258 struct ctldebug debug0 = { "syncprt", &syncprt };
259 #endif
260 
261 struct sync_args {
262 	int	dummy;
263 };
264 /* ARGSUSED */
265 sync(p, uap, retval)
266 	struct proc *p;
267 	struct sync_args *uap;
268 	int *retval;
269 {
270 	register struct mount *mp, *nmp;
271 	int asyncflag;
272 
273 	for (mp = mountlist.tqh_first; mp != NULL; mp = nmp) {
274 		nmp = mp->mnt_list.tqe_next;
275 		/*
276 		 * The lock check below is to avoid races with mount
277 		 * and unmount.
278 		 */
279 		if ((mp->mnt_flag & (MNT_MLOCK|MNT_RDONLY|MNT_MPBUSY)) == 0 &&
280 		    !vfs_busy(mp)) {
281 			asyncflag = mp->mnt_flag & MNT_ASYNC;
282 			mp->mnt_flag &= ~MNT_ASYNC;
283 			VFS_SYNC(mp, MNT_NOWAIT, p->p_ucred, p);
284 			if (asyncflag)
285 				mp->mnt_flag |= MNT_ASYNC;
286 			vfs_unbusy(mp);
287 		}
288 	}
289 #ifdef DIAGNOSTIC
290 	if (syncprt)
291 		vfs_bufstats();
292 #endif /* DIAGNOSTIC */
293 	return (0);
294 }
295 
296 /*
297  * Change filesystem quotas.
298  */
299 struct quotactl_args {
300 	char *path;
301 	int cmd;
302 	int uid;
303 	caddr_t arg;
304 };
305 /* ARGSUSED */
306 quotactl(p, uap, retval)
307 	struct proc *p;
308 	register struct quotactl_args *uap;
309 	int *retval;
310 {
311 	register struct mount *mp;
312 	int error;
313 	struct nameidata nd;
314 
315 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
316 	if (error = namei(&nd))
317 		return (error);
318 	mp = nd.ni_vp->v_mount;
319 	vrele(nd.ni_vp);
320 	return (VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg, p));
321 }
322 
323 /*
324  * Get filesystem statistics.
325  */
326 struct statfs_args {
327 	char *path;
328 	struct statfs *buf;
329 };
330 /* ARGSUSED */
331 statfs(p, uap, retval)
332 	struct proc *p;
333 	register struct statfs_args *uap;
334 	int *retval;
335 {
336 	register struct mount *mp;
337 	register struct statfs *sp;
338 	int error;
339 	struct nameidata nd;
340 
341 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
342 	if (error = namei(&nd))
343 		return (error);
344 	mp = nd.ni_vp->v_mount;
345 	sp = &mp->mnt_stat;
346 	vrele(nd.ni_vp);
347 	if (error = VFS_STATFS(mp, sp, p))
348 		return (error);
349 	sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
350 	return (copyout((caddr_t)sp, (caddr_t)uap->buf, sizeof(*sp)));
351 }
352 
353 /*
354  * Get filesystem statistics.
355  */
356 struct fstatfs_args {
357 	int fd;
358 	struct statfs *buf;
359 };
360 /* ARGSUSED */
361 fstatfs(p, uap, retval)
362 	struct proc *p;
363 	register struct fstatfs_args *uap;
364 	int *retval;
365 {
366 	struct file *fp;
367 	struct mount *mp;
368 	register struct statfs *sp;
369 	int error;
370 
371 	if (error = getvnode(p->p_fd, uap->fd, &fp))
372 		return (error);
373 	mp = ((struct vnode *)fp->f_data)->v_mount;
374 	sp = &mp->mnt_stat;
375 	if (error = VFS_STATFS(mp, sp, p))
376 		return (error);
377 	sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
378 	return (copyout((caddr_t)sp, (caddr_t)uap->buf, sizeof(*sp)));
379 }
380 
381 /*
382  * Get statistics on all filesystems.
383  */
384 struct getfsstat_args {
385 	struct statfs *buf;
386 	long bufsize;
387 	int flags;
388 };
389 getfsstat(p, uap, retval)
390 	struct proc *p;
391 	register struct getfsstat_args *uap;
392 	int *retval;
393 {
394 	register struct mount *mp, *nmp;
395 	register struct statfs *sp;
396 	caddr_t sfsp;
397 	long count, maxcount, error;
398 
399 	maxcount = uap->bufsize / sizeof(struct statfs);
400 	sfsp = (caddr_t)uap->buf;
401 	for (count = 0, mp = mountlist.tqh_first; mp != NULL; mp = nmp) {
402 		nmp = mp->mnt_list.tqe_next;
403 		if (sfsp && count < maxcount &&
404 		    ((mp->mnt_flag & MNT_MLOCK) == 0)) {
405 			sp = &mp->mnt_stat;
406 			/*
407 			 * If MNT_NOWAIT is specified, do not refresh the
408 			 * fsstat cache. MNT_WAIT overrides MNT_NOWAIT.
409 			 */
410 			if (((uap->flags & MNT_NOWAIT) == 0 ||
411 			    (uap->flags & MNT_WAIT)) &&
412 			    (error = VFS_STATFS(mp, sp, p)))
413 				continue;
414 			sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
415 			if (error = copyout((caddr_t)sp, sfsp, sizeof(*sp)))
416 				return (error);
417 			sfsp += sizeof(*sp);
418 		}
419 		count++;
420 	}
421 	if (sfsp && count > maxcount)
422 		*retval = maxcount;
423 	else
424 		*retval = count;
425 	return (0);
426 }
427 
428 /*
429  * Change current working directory to a given file descriptor.
430  */
431 struct fchdir_args {
432 	int	fd;
433 };
434 /* ARGSUSED */
435 fchdir(p, uap, retval)
436 	struct proc *p;
437 	struct fchdir_args *uap;
438 	int *retval;
439 {
440 	register struct filedesc *fdp = p->p_fd;
441 	register struct vnode *vp;
442 	struct file *fp;
443 	int error;
444 
445 	if (error = getvnode(fdp, uap->fd, &fp))
446 		return (error);
447 	vp = (struct vnode *)fp->f_data;
448 	VOP_LOCK(vp);
449 	if (vp->v_type != VDIR)
450 		error = ENOTDIR;
451 	else
452 		error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
453 	VOP_UNLOCK(vp);
454 	if (error)
455 		return (error);
456 	VREF(vp);
457 	vrele(fdp->fd_cdir);
458 	fdp->fd_cdir = vp;
459 	return (0);
460 }
461 
462 /*
463  * Change current working directory (``.'').
464  */
465 struct chdir_args {
466 	char	*path;
467 };
468 /* ARGSUSED */
469 chdir(p, uap, retval)
470 	struct proc *p;
471 	struct chdir_args *uap;
472 	int *retval;
473 {
474 	register struct filedesc *fdp = p->p_fd;
475 	int error;
476 	struct nameidata nd;
477 
478 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
479 	if (error = change_dir(&nd, p))
480 		return (error);
481 	vrele(fdp->fd_cdir);
482 	fdp->fd_cdir = nd.ni_vp;
483 	return (0);
484 }
485 
486 /*
487  * Change notion of root (``/'') directory.
488  */
489 struct chroot_args {
490 	char	*path;
491 };
492 /* ARGSUSED */
493 chroot(p, uap, retval)
494 	struct proc *p;
495 	struct chroot_args *uap;
496 	int *retval;
497 {
498 	register struct filedesc *fdp = p->p_fd;
499 	int error;
500 	struct nameidata nd;
501 
502 	if (error = suser(p->p_ucred, &p->p_acflag))
503 		return (error);
504 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
505 	if (error = change_dir(&nd, p))
506 		return (error);
507 	if (fdp->fd_rdir != NULL)
508 		vrele(fdp->fd_rdir);
509 	fdp->fd_rdir = nd.ni_vp;
510 	return (0);
511 }
512 
513 /*
514  * Common routine for chroot and chdir.
515  */
516 static int
517 change_dir(ndp, p)
518 	register struct nameidata *ndp;
519 	struct proc *p;
520 {
521 	struct vnode *vp;
522 	int error;
523 
524 	if (error = namei(ndp))
525 		return (error);
526 	vp = ndp->ni_vp;
527 	if (vp->v_type != VDIR)
528 		error = ENOTDIR;
529 	else
530 		error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
531 	VOP_UNLOCK(vp);
532 	if (error)
533 		vrele(vp);
534 	return (error);
535 }
536 
537 /*
538  * Check permissions, allocate an open file structure,
539  * and call the device open routine if any.
540  */
541 struct open_args {
542 	char	*path;
543 	int	flags;
544 	int	mode;
545 };
546 open(p, uap, retval)
547 	struct proc *p;
548 	register struct open_args *uap;
549 	int *retval;
550 {
551 	register struct filedesc *fdp = p->p_fd;
552 	register struct file *fp;
553 	register struct vnode *vp;
554 	int flags, cmode;
555 	struct file *nfp;
556 	int type, indx, error;
557 	struct flock lf;
558 	struct nameidata nd;
559 	extern struct fileops vnops;
560 
561 	if (error = falloc(p, &nfp, &indx))
562 		return (error);
563 	fp = nfp;
564 	flags = FFLAGS(uap->flags);
565 	cmode = ((uap->mode &~ fdp->fd_cmask) & ALLPERMS) &~ S_ISTXT;
566 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
567 	p->p_dupfd = -indx - 1;			/* XXX check for fdopen */
568 	if (error = vn_open(&nd, flags, cmode)) {
569 		ffree(fp);
570 		if ((error == ENODEV || error == ENXIO) &&
571 		    p->p_dupfd >= 0 && 			/* XXX from fdopen */
572 		    (error =
573 		        dupfdopen(fdp, indx, p->p_dupfd, flags, error)) == 0) {
574 			*retval = indx;
575 			return (0);
576 		}
577 		if (error == ERESTART)
578 			error = EINTR;
579 		fdp->fd_ofiles[indx] = NULL;
580 		return (error);
581 	}
582 	p->p_dupfd = 0;
583 	vp = nd.ni_vp;
584 	fp->f_flag = flags & FMASK;
585 	fp->f_type = DTYPE_VNODE;
586 	fp->f_ops = &vnops;
587 	fp->f_data = (caddr_t)vp;
588 	if (flags & (O_EXLOCK | O_SHLOCK)) {
589 		lf.l_whence = SEEK_SET;
590 		lf.l_start = 0;
591 		lf.l_len = 0;
592 		if (flags & O_EXLOCK)
593 			lf.l_type = F_WRLCK;
594 		else
595 			lf.l_type = F_RDLCK;
596 		type = F_FLOCK;
597 		if ((flags & FNONBLOCK) == 0)
598 			type |= F_WAIT;
599 		VOP_UNLOCK(vp);
600 		if (error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) {
601 			(void) vn_close(vp, fp->f_flag, fp->f_cred, p);
602 			ffree(fp);
603 			fdp->fd_ofiles[indx] = NULL;
604 			return (error);
605 		}
606 		VOP_LOCK(vp);
607 		fp->f_flag |= FHASLOCK;
608 	}
609 	VOP_UNLOCK(vp);
610 	*retval = indx;
611 	return (0);
612 }
613 
614 #ifdef COMPAT_43
615 /*
616  * Create a file.
617  */
618 struct ocreat_args {
619 	char	*path;
620 	int	mode;
621 };
622 ocreat(p, uap, retval)
623 	struct proc *p;
624 	register struct ocreat_args *uap;
625 	int *retval;
626 {
627 	struct open_args openuap;
628 
629 	openuap.path = uap->path;
630 	openuap.mode = uap->mode;
631 	openuap.flags = O_WRONLY | O_CREAT | O_TRUNC;
632 	return (open(p, &openuap, retval));
633 }
634 #endif /* COMPAT_43 */
635 
636 /*
637  * Create a special file.
638  */
639 struct mknod_args {
640 	char	*path;
641 	int	mode;
642 	int	dev;
643 };
644 /* ARGSUSED */
645 mknod(p, uap, retval)
646 	struct proc *p;
647 	register struct mknod_args *uap;
648 	int *retval;
649 {
650 	register struct vnode *vp;
651 	struct vattr vattr;
652 	int error;
653 	struct nameidata nd;
654 
655 	if (error = suser(p->p_ucred, &p->p_acflag))
656 		return (error);
657 	NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->path, p);
658 	if (error = namei(&nd))
659 		return (error);
660 	vp = nd.ni_vp;
661 	if (vp != NULL)
662 		error = EEXIST;
663 	else {
664 		VATTR_NULL(&vattr);
665 		vattr.va_mode = (uap->mode & ALLPERMS) &~ p->p_fd->fd_cmask;
666 		vattr.va_rdev = uap->dev;
667 
668 		switch (uap->mode & S_IFMT) {
669 		case S_IFMT:	/* used by badsect to flag bad sectors */
670 			vattr.va_type = VBAD;
671 			break;
672 		case S_IFCHR:
673 			vattr.va_type = VCHR;
674 			break;
675 		case S_IFBLK:
676 			vattr.va_type = VBLK;
677 			break;
678 		default:
679 			error = EINVAL;
680 			break;
681 		}
682 	}
683 	if (!error) {
684 		LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
685 		error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
686 	} else {
687 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
688 		if (nd.ni_dvp == vp)
689 			vrele(nd.ni_dvp);
690 		else
691 			vput(nd.ni_dvp);
692 		if (vp)
693 			vrele(vp);
694 	}
695 	return (error);
696 }
697 
698 /*
699  * Create named pipe.
700  */
701 struct mkfifo_args {
702 	char	*path;
703 	int	mode;
704 };
705 /* ARGSUSED */
706 mkfifo(p, uap, retval)
707 	struct proc *p;
708 	register struct mkfifo_args *uap;
709 	int *retval;
710 {
711 	struct vattr vattr;
712 	int error;
713 	struct nameidata nd;
714 
715 #ifndef FIFO
716 	return (EOPNOTSUPP);
717 #else
718 	NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->path, p);
719 	if (error = namei(&nd))
720 		return (error);
721 	if (nd.ni_vp != NULL) {
722 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
723 		if (nd.ni_dvp == nd.ni_vp)
724 			vrele(nd.ni_dvp);
725 		else
726 			vput(nd.ni_dvp);
727 		vrele(nd.ni_vp);
728 		return (EEXIST);
729 	}
730 	VATTR_NULL(&vattr);
731 	vattr.va_type = VFIFO;
732 	vattr.va_mode = (uap->mode & ALLPERMS) &~ p->p_fd->fd_cmask;
733 	LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
734 	return (VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr));
735 #endif /* FIFO */
736 }
737 
738 /*
739  * Make a hard file link.
740  */
741 struct link_args {
742 	char	*path;
743 	char	*link;
744 };
745 /* ARGSUSED */
746 link(p, uap, retval)
747 	struct proc *p;
748 	register struct link_args *uap;
749 	int *retval;
750 {
751 	register struct vnode *vp;
752 	struct nameidata nd;
753 	int error;
754 
755 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
756 	if (error = namei(&nd))
757 		return (error);
758 	vp = nd.ni_vp;
759 	if (vp->v_type != VDIR ||
760 	    (error = suser(p->p_ucred, &p->p_acflag)) == 0) {
761 		nd.ni_cnd.cn_nameiop = CREATE;
762 		nd.ni_cnd.cn_flags = LOCKPARENT;
763 		nd.ni_dirp = uap->link;
764 		if ((error = namei(&nd)) == 0) {
765 			if (nd.ni_vp != NULL)
766 				error = EEXIST;
767 			if (!error) {
768 				LEASE_CHECK(nd.ni_dvp,
769 				    p, p->p_ucred, LEASE_WRITE);
770 				LEASE_CHECK(vp,
771 				    p, p->p_ucred, LEASE_WRITE);
772 				error = VOP_LINK(nd.ni_dvp, vp, &nd.ni_cnd);
773 			} else {
774 				VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
775 				if (nd.ni_dvp == nd.ni_vp)
776 					vrele(nd.ni_dvp);
777 				else
778 					vput(nd.ni_dvp);
779 				if (nd.ni_vp)
780 					vrele(nd.ni_vp);
781 			}
782 		}
783 	}
784 	vrele(vp);
785 	return (error);
786 }
787 
788 /*
789  * Make a symbolic link.
790  */
791 struct symlink_args {
792 	char	*path;
793 	char	*link;
794 };
795 /* ARGSUSED */
796 symlink(p, uap, retval)
797 	struct proc *p;
798 	register struct symlink_args *uap;
799 	int *retval;
800 {
801 	struct vattr vattr;
802 	char *path;
803 	int error;
804 	struct nameidata nd;
805 
806 	MALLOC(path, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
807 	if (error = copyinstr(uap->path, path, MAXPATHLEN, NULL))
808 		goto out;
809 	NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->link, p);
810 	if (error = namei(&nd))
811 		goto out;
812 	if (nd.ni_vp) {
813 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
814 		if (nd.ni_dvp == nd.ni_vp)
815 			vrele(nd.ni_dvp);
816 		else
817 			vput(nd.ni_dvp);
818 		vrele(nd.ni_vp);
819 		error = EEXIST;
820 		goto out;
821 	}
822 	VATTR_NULL(&vattr);
823 	vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask;
824 	LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
825 	error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr, path);
826 out:
827 	FREE(path, M_NAMEI);
828 	return (error);
829 }
830 
831 /*
832  * Delete a name from the filesystem.
833  */
834 struct unlink_args {
835 	char	*path;
836 };
837 /* ARGSUSED */
838 unlink(p, uap, retval)
839 	struct proc *p;
840 	struct unlink_args *uap;
841 	int *retval;
842 {
843 	register struct vnode *vp;
844 	int error;
845 	struct nameidata nd;
846 
847 	NDINIT(&nd, DELETE, LOCKPARENT, UIO_USERSPACE, uap->path, p);
848 	if (error = namei(&nd))
849 		return (error);
850 	vp = nd.ni_vp;
851 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
852 	VOP_LOCK(vp);
853 
854 	if (vp->v_type != VDIR ||
855 	    (error = suser(p->p_ucred, &p->p_acflag)) == 0) {
856 		/*
857 		 * The root of a mounted filesystem cannot be deleted.
858 		 */
859 		if (vp->v_flag & VROOT)
860 			error = EBUSY;
861 		else
862 			(void)vnode_pager_uncache(vp);
863 	}
864 
865 	if (!error) {
866 		LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
867 		error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
868 	} else {
869 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
870 		if (nd.ni_dvp == vp)
871 			vrele(nd.ni_dvp);
872 		else
873 			vput(nd.ni_dvp);
874 		vput(vp);
875 	}
876 	return (error);
877 }
878 
879 /*
880  * Reposition read/write file offset.
881  */
882 struct lseek_args {
883 	int	fd;
884 	int	pad;
885 	off_t	offset;
886 	int	whence;
887 };
888 lseek(p, uap, retval)
889 	struct proc *p;
890 	register struct lseek_args *uap;
891 	int *retval;
892 {
893 	struct ucred *cred = p->p_ucred;
894 	register struct filedesc *fdp = p->p_fd;
895 	register struct file *fp;
896 	struct vattr vattr;
897 	int error;
898 
899 	if ((u_int)uap->fd >= fdp->fd_nfiles ||
900 	    (fp = fdp->fd_ofiles[uap->fd]) == NULL)
901 		return (EBADF);
902 	if (fp->f_type != DTYPE_VNODE)
903 		return (ESPIPE);
904 	switch (uap->whence) {
905 	case L_INCR:
906 		fp->f_offset += uap->offset;
907 		break;
908 	case L_XTND:
909 		if (error =
910 		    VOP_GETATTR((struct vnode *)fp->f_data, &vattr, cred, p))
911 			return (error);
912 		fp->f_offset = uap->offset + vattr.va_size;
913 		break;
914 	case L_SET:
915 		fp->f_offset = uap->offset;
916 		break;
917 	default:
918 		return (EINVAL);
919 	}
920 	*(off_t *)retval = fp->f_offset;
921 	return (0);
922 }
923 
924 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
925 /*
926  * Reposition read/write file offset.
927  */
928 struct olseek_args {
929 	int	fd;
930 	long	offset;
931 	int	whence;
932 };
933 olseek(p, uap, retval)
934 	struct proc *p;
935 	register struct olseek_args *uap;
936 	int *retval;
937 {
938 	struct lseek_args nuap;
939 	off_t qret;
940 	int error;
941 
942 	nuap.fd = uap->fd;
943 	nuap.offset = uap->offset;
944 	nuap.whence = uap->whence;
945 	error = lseek(p, &nuap, &qret);
946 	*(long *)retval = qret;
947 	return (error);
948 }
949 #endif /* COMPAT_43 */
950 
951 /*
952  * Check access permissions.
953  */
954 struct access_args {
955 	char	*path;
956 	int	flags;
957 };
958 access(p, uap, retval)
959 	struct proc *p;
960 	register struct access_args *uap;
961 	int *retval;
962 {
963 	register struct ucred *cred = p->p_ucred;
964 	register struct vnode *vp;
965 	int error, flags, t_gid, t_uid;
966 	struct nameidata nd;
967 
968 	t_uid = cred->cr_uid;
969 	t_gid = cred->cr_groups[0];
970 	cred->cr_uid = p->p_cred->p_ruid;
971 	cred->cr_groups[0] = p->p_cred->p_rgid;
972 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
973 	if (error = namei(&nd))
974 		goto out1;
975 	vp = nd.ni_vp;
976 
977 	/* Flags == 0 means only check for existence. */
978 	if (uap->flags) {
979 		flags = 0;
980 		if (uap->flags & R_OK)
981 			flags |= VREAD;
982 		if (uap->flags & W_OK)
983 			flags |= VWRITE;
984 		if (uap->flags & X_OK)
985 			flags |= VEXEC;
986 		if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
987 			error = VOP_ACCESS(vp, flags, cred, p);
988 	}
989 	vput(vp);
990 out1:
991 	cred->cr_uid = t_uid;
992 	cred->cr_groups[0] = t_gid;
993 	return (error);
994 }
995 
996 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
997 /*
998  * Get file status; this version follows links.
999  */
1000 struct ostat_args {
1001 	char	*path;
1002 	struct ostat *ub;
1003 };
1004 /* ARGSUSED */
1005 ostat(p, uap, retval)
1006 	struct proc *p;
1007 	register struct ostat_args *uap;
1008 	int *retval;
1009 {
1010 	struct stat sb;
1011 	struct ostat osb;
1012 	int error;
1013 	struct nameidata nd;
1014 
1015 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
1016 	if (error = namei(&nd))
1017 		return (error);
1018 	error = vn_stat(nd.ni_vp, &sb, p);
1019 	vput(nd.ni_vp);
1020 	if (error)
1021 		return (error);
1022 	cvtstat(&sb, &osb);
1023 	error = copyout((caddr_t)&osb, (caddr_t)uap->ub, sizeof (osb));
1024 	return (error);
1025 }
1026 
1027 /*
1028  * Get file status; this version does not follow links.
1029  */
1030 struct olstat_args {
1031 	char	*path;
1032 	struct ostat *ub;
1033 };
1034 /* ARGSUSED */
1035 olstat(p, uap, retval)
1036 	struct proc *p;
1037 	register struct olstat_args *uap;
1038 	int *retval;
1039 {
1040 	struct stat sb;
1041 	struct ostat osb;
1042 	int error;
1043 	struct nameidata nd;
1044 
1045 	NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
1046 	if (error = namei(&nd))
1047 		return (error);
1048 	error = vn_stat(nd.ni_vp, &sb, p);
1049 	vput(nd.ni_vp);
1050 	if (error)
1051 		return (error);
1052 	cvtstat(&sb, &osb);
1053 	error = copyout((caddr_t)&osb, (caddr_t)uap->ub, sizeof (osb));
1054 	return (error);
1055 }
1056 
1057 /*
1058  * Convert from an old to a new stat structure.
1059  */
1060 cvtstat(st, ost)
1061 	struct stat *st;
1062 	struct ostat *ost;
1063 {
1064 
1065 	ost->st_dev = st->st_dev;
1066 	ost->st_ino = st->st_ino;
1067 	ost->st_mode = st->st_mode;
1068 	ost->st_nlink = st->st_nlink;
1069 	ost->st_uid = st->st_uid;
1070 	ost->st_gid = st->st_gid;
1071 	ost->st_rdev = st->st_rdev;
1072 	if (st->st_size < (quad_t)1 << 32)
1073 		ost->st_size = st->st_size;
1074 	else
1075 		ost->st_size = -2;
1076 	ost->st_atime = st->st_atime;
1077 	ost->st_mtime = st->st_mtime;
1078 	ost->st_ctime = st->st_ctime;
1079 	ost->st_blksize = st->st_blksize;
1080 	ost->st_blocks = st->st_blocks;
1081 	ost->st_flags = st->st_flags;
1082 	ost->st_gen = st->st_gen;
1083 }
1084 #endif /* COMPAT_43 || COMPAT_SUNOS */
1085 
1086 /*
1087  * Get file status; this version follows links.
1088  */
1089 struct stat_args {
1090 	char	*path;
1091 	struct stat *ub;
1092 };
1093 /* ARGSUSED */
1094 stat(p, uap, retval)
1095 	struct proc *p;
1096 	register struct stat_args *uap;
1097 	int *retval;
1098 {
1099 	struct stat sb;
1100 	int error;
1101 	struct nameidata nd;
1102 
1103 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
1104 	if (error = namei(&nd))
1105 		return (error);
1106 	error = vn_stat(nd.ni_vp, &sb, p);
1107 	vput(nd.ni_vp);
1108 	if (error)
1109 		return (error);
1110 	error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
1111 	return (error);
1112 }
1113 
1114 /*
1115  * Get file status; this version does not follow links.
1116  */
1117 struct lstat_args {
1118 	char	*path;
1119 	struct stat *ub;
1120 };
1121 /* ARGSUSED */
1122 lstat(p, uap, retval)
1123 	struct proc *p;
1124 	register struct lstat_args *uap;
1125 	int *retval;
1126 {
1127 	int error;
1128 	struct vnode *vp, *dvp;
1129 	struct stat sb, sb1;
1130 	struct nameidata nd;
1131 
1132 	NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKPARENT, UIO_USERSPACE,
1133 	    uap->path, p);
1134 	if (error = namei(&nd))
1135 		return (error);
1136 	/*
1137 	 * For symbolic links, always return the attributes of its
1138 	 * containing directory, except for mode, size, and links.
1139 	 */
1140 	vp = nd.ni_vp;
1141 	dvp = nd.ni_dvp;
1142 	if (vp->v_type != VLNK) {
1143 		if (dvp == vp)
1144 			vrele(dvp);
1145 		else
1146 			vput(dvp);
1147 		error = vn_stat(vp, &sb, p);
1148 		vput(vp);
1149 		if (error)
1150 			return (error);
1151 	} else {
1152 		error = vn_stat(dvp, &sb, p);
1153 		vput(dvp);
1154 		if (error) {
1155 			vput(vp);
1156 			return (error);
1157 		}
1158 		error = vn_stat(vp, &sb1, p);
1159 		vput(vp);
1160 		if (error)
1161 			return (error);
1162 		sb.st_mode &= ~S_IFDIR;
1163 		sb.st_mode |= S_IFLNK;
1164 		sb.st_nlink = sb1.st_nlink;
1165 		sb.st_size = sb1.st_size;
1166 		sb.st_blocks = sb1.st_blocks;
1167 	}
1168 	error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
1169 	return (error);
1170 }
1171 
1172 /*
1173  * Get configurable pathname variables.
1174  */
1175 struct pathconf_args {
1176 	char	*path;
1177 	int	name;
1178 };
1179 /* ARGSUSED */
1180 pathconf(p, uap, retval)
1181 	struct proc *p;
1182 	register struct pathconf_args *uap;
1183 	int *retval;
1184 {
1185 	int error;
1186 	struct nameidata nd;
1187 
1188 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
1189 	if (error = namei(&nd))
1190 		return (error);
1191 	error = VOP_PATHCONF(nd.ni_vp, uap->name, retval);
1192 	vput(nd.ni_vp);
1193 	return (error);
1194 }
1195 
1196 /*
1197  * Return target name of a symbolic link.
1198  */
1199 struct readlink_args {
1200 	char	*path;
1201 	char	*buf;
1202 	int	count;
1203 };
1204 /* ARGSUSED */
1205 readlink(p, uap, retval)
1206 	struct proc *p;
1207 	register struct readlink_args *uap;
1208 	int *retval;
1209 {
1210 	register struct vnode *vp;
1211 	struct iovec aiov;
1212 	struct uio auio;
1213 	int error;
1214 	struct nameidata nd;
1215 
1216 	NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE, uap->path, p);
1217 	if (error = namei(&nd))
1218 		return (error);
1219 	vp = nd.ni_vp;
1220 	if (vp->v_type != VLNK)
1221 		error = EINVAL;
1222 	else {
1223 		aiov.iov_base = uap->buf;
1224 		aiov.iov_len = uap->count;
1225 		auio.uio_iov = &aiov;
1226 		auio.uio_iovcnt = 1;
1227 		auio.uio_offset = 0;
1228 		auio.uio_rw = UIO_READ;
1229 		auio.uio_segflg = UIO_USERSPACE;
1230 		auio.uio_procp = p;
1231 		auio.uio_resid = uap->count;
1232 		error = VOP_READLINK(vp, &auio, p->p_ucred);
1233 	}
1234 	vput(vp);
1235 	*retval = uap->count - auio.uio_resid;
1236 	return (error);
1237 }
1238 
1239 /*
1240  * Change flags of a file given a path name.
1241  */
1242 struct chflags_args {
1243 	char	*path;
1244 	int	flags;
1245 };
1246 /* ARGSUSED */
1247 chflags(p, uap, retval)
1248 	struct proc *p;
1249 	register struct chflags_args *uap;
1250 	int *retval;
1251 {
1252 	register struct vnode *vp;
1253 	struct vattr vattr;
1254 	int error;
1255 	struct nameidata nd;
1256 
1257 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
1258 	if (error = namei(&nd))
1259 		return (error);
1260 	vp = nd.ni_vp;
1261 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1262 	VOP_LOCK(vp);
1263 	if (vp->v_mount->mnt_flag & MNT_RDONLY)
1264 		error = EROFS;
1265 	else {
1266 		VATTR_NULL(&vattr);
1267 		vattr.va_flags = uap->flags;
1268 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1269 	}
1270 	vput(vp);
1271 	return (error);
1272 }
1273 
1274 /*
1275  * Change flags of a file given a file descriptor.
1276  */
1277 struct fchflags_args {
1278 	int	fd;
1279 	int	flags;
1280 };
1281 /* ARGSUSED */
1282 fchflags(p, uap, retval)
1283 	struct proc *p;
1284 	register struct fchflags_args *uap;
1285 	int *retval;
1286 {
1287 	struct vattr vattr;
1288 	struct vnode *vp;
1289 	struct file *fp;
1290 	int error;
1291 
1292 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1293 		return (error);
1294 	vp = (struct vnode *)fp->f_data;
1295 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1296 	VOP_LOCK(vp);
1297 	if (vp->v_mount->mnt_flag & MNT_RDONLY)
1298 		error = EROFS;
1299 	else {
1300 		VATTR_NULL(&vattr);
1301 		vattr.va_flags = uap->flags;
1302 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1303 	}
1304 	VOP_UNLOCK(vp);
1305 	return (error);
1306 }
1307 
1308 /*
1309  * Change mode of a file given path name.
1310  */
1311 struct chmod_args {
1312 	char	*path;
1313 	int	mode;
1314 };
1315 /* ARGSUSED */
1316 chmod(p, uap, retval)
1317 	struct proc *p;
1318 	register struct chmod_args *uap;
1319 	int *retval;
1320 {
1321 	register struct vnode *vp;
1322 	struct vattr vattr;
1323 	int error;
1324 	struct nameidata nd;
1325 
1326 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
1327 	if (error = namei(&nd))
1328 		return (error);
1329 	vp = nd.ni_vp;
1330 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1331 	VOP_LOCK(vp);
1332 	if (vp->v_mount->mnt_flag & MNT_RDONLY)
1333 		error = EROFS;
1334 	else {
1335 		VATTR_NULL(&vattr);
1336 		vattr.va_mode = uap->mode & ALLPERMS;
1337 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1338 	}
1339 	vput(vp);
1340 	return (error);
1341 }
1342 
1343 /*
1344  * Change mode of a file given a file descriptor.
1345  */
1346 struct fchmod_args {
1347 	int	fd;
1348 	int	mode;
1349 };
1350 /* ARGSUSED */
1351 fchmod(p, uap, retval)
1352 	struct proc *p;
1353 	register struct fchmod_args *uap;
1354 	int *retval;
1355 {
1356 	struct vattr vattr;
1357 	struct vnode *vp;
1358 	struct file *fp;
1359 	int error;
1360 
1361 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1362 		return (error);
1363 	vp = (struct vnode *)fp->f_data;
1364 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1365 	VOP_LOCK(vp);
1366 	if (vp->v_mount->mnt_flag & MNT_RDONLY)
1367 		error = EROFS;
1368 	else {
1369 		VATTR_NULL(&vattr);
1370 		vattr.va_mode = uap->mode & ALLPERMS;
1371 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1372 	}
1373 	VOP_UNLOCK(vp);
1374 	return (error);
1375 }
1376 
1377 /*
1378  * Set ownership given a path name.
1379  */
1380 struct chown_args {
1381 	char	*path;
1382 	int	uid;
1383 	int	gid;
1384 };
1385 /* ARGSUSED */
1386 chown(p, uap, retval)
1387 	struct proc *p;
1388 	register struct chown_args *uap;
1389 	int *retval;
1390 {
1391 	register struct vnode *vp;
1392 	struct vattr vattr;
1393 	int error;
1394 	struct nameidata nd;
1395 
1396 	NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->path, p);
1397 	if (error = namei(&nd))
1398 		return (error);
1399 	vp = nd.ni_vp;
1400 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1401 	VOP_LOCK(vp);
1402 	if (vp->v_mount->mnt_flag & MNT_RDONLY)
1403 		error = EROFS;
1404 	else {
1405 		VATTR_NULL(&vattr);
1406 		vattr.va_uid = uap->uid;
1407 		vattr.va_gid = uap->gid;
1408 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1409 	}
1410 	vput(vp);
1411 	return (error);
1412 }
1413 
1414 /*
1415  * Set ownership given a file descriptor.
1416  */
1417 struct fchown_args {
1418 	int	fd;
1419 	int	uid;
1420 	int	gid;
1421 };
1422 /* ARGSUSED */
1423 fchown(p, uap, retval)
1424 	struct proc *p;
1425 	register struct fchown_args *uap;
1426 	int *retval;
1427 {
1428 	struct vattr vattr;
1429 	struct vnode *vp;
1430 	struct file *fp;
1431 	int error;
1432 
1433 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1434 		return (error);
1435 	vp = (struct vnode *)fp->f_data;
1436 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1437 	VOP_LOCK(vp);
1438 	if (vp->v_mount->mnt_flag & MNT_RDONLY)
1439 		error = EROFS;
1440 	else {
1441 		VATTR_NULL(&vattr);
1442 		vattr.va_uid = uap->uid;
1443 		vattr.va_gid = uap->gid;
1444 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1445 	}
1446 	VOP_UNLOCK(vp);
1447 	return (error);
1448 }
1449 
1450 /*
1451  * Set the access and modification times of a file.
1452  */
1453 struct utimes_args {
1454 	char	*path;
1455 	struct	timeval *tptr;
1456 };
1457 /* ARGSUSED */
1458 utimes(p, uap, retval)
1459 	struct proc *p;
1460 	register struct utimes_args *uap;
1461 	int *retval;
1462 {
1463 	register struct vnode *vp;
1464 	struct timeval tv[2];
1465 	struct vattr vattr;
1466 	int error;
1467 	struct nameidata nd;
1468 
1469 	VATTR_NULL(&vattr);
1470 	if (uap->tptr == NULL) {
1471 		microtime(&tv[0]);
1472 		tv[1] = tv[0];
1473 		vattr.va_vaflags |= VA_UTIMES_NULL;
1474 	} else if (error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)))
1475   		return (error);
1476 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
1477 	if (error = namei(&nd))
1478 		return (error);
1479 	vp = nd.ni_vp;
1480 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1481 	VOP_LOCK(vp);
1482 	if (vp->v_mount->mnt_flag & MNT_RDONLY)
1483 		error = EROFS;
1484 	else {
1485 		vattr.va_atime.ts_sec = tv[0].tv_sec;
1486 		vattr.va_atime.ts_nsec = tv[0].tv_usec * 1000;
1487 		vattr.va_mtime.ts_sec = tv[1].tv_sec;
1488 		vattr.va_mtime.ts_nsec = tv[1].tv_usec * 1000;
1489 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1490 	}
1491 	vput(vp);
1492 	return (error);
1493 }
1494 
1495 /*
1496  * Truncate a file given its path name.
1497  */
1498 struct truncate_args {
1499 	char	*path;
1500 	int	pad;
1501 	off_t	length;
1502 };
1503 /* ARGSUSED */
1504 truncate(p, uap, retval)
1505 	struct proc *p;
1506 	register struct truncate_args *uap;
1507 	int *retval;
1508 {
1509 	register struct vnode *vp;
1510 	struct vattr vattr;
1511 	int error;
1512 	struct nameidata nd;
1513 
1514 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
1515 	if (error = namei(&nd))
1516 		return (error);
1517 	vp = nd.ni_vp;
1518 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1519 	VOP_LOCK(vp);
1520 	if (vp->v_type == VDIR)
1521 		error = EISDIR;
1522 	else if ((error = vn_writechk(vp)) == 0 &&
1523 	    (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, p)) == 0) {
1524 		VATTR_NULL(&vattr);
1525 		vattr.va_size = uap->length;
1526 		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1527 	}
1528 	vput(vp);
1529 	return (error);
1530 }
1531 
1532 /*
1533  * Truncate a file given a file descriptor.
1534  */
1535 struct ftruncate_args {
1536 	int	fd;
1537 	int	pad;
1538 	off_t	length;
1539 };
1540 /* ARGSUSED */
1541 ftruncate(p, uap, retval)
1542 	struct proc *p;
1543 	register struct ftruncate_args *uap;
1544 	int *retval;
1545 {
1546 	struct vattr vattr;
1547 	struct vnode *vp;
1548 	struct file *fp;
1549 	int error;
1550 
1551 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1552 		return (error);
1553 	if ((fp->f_flag & FWRITE) == 0)
1554 		return (EINVAL);
1555 	vp = (struct vnode *)fp->f_data;
1556 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1557 	VOP_LOCK(vp);
1558 	if (vp->v_type == VDIR)
1559 		error = EISDIR;
1560 	else if ((error = vn_writechk(vp)) == 0) {
1561 		VATTR_NULL(&vattr);
1562 		vattr.va_size = uap->length;
1563 		error = VOP_SETATTR(vp, &vattr, fp->f_cred, p);
1564 	}
1565 	VOP_UNLOCK(vp);
1566 	return (error);
1567 }
1568 
1569 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1570 /*
1571  * Truncate a file given its path name.
1572  */
1573 struct otruncate_args {
1574 	char	*path;
1575 	long	length;
1576 };
1577 /* ARGSUSED */
1578 otruncate(p, uap, retval)
1579 	struct proc *p;
1580 	register struct otruncate_args *uap;
1581 	int *retval;
1582 {
1583 	struct truncate_args nuap;
1584 
1585 	nuap.path = uap->path;
1586 	nuap.length = uap->length;
1587 	return (truncate(p, &nuap, retval));
1588 }
1589 
1590 /*
1591  * Truncate a file given a file descriptor.
1592  */
1593 struct oftruncate_args {
1594 	int	fd;
1595 	long	length;
1596 };
1597 /* ARGSUSED */
1598 oftruncate(p, uap, retval)
1599 	struct proc *p;
1600 	register struct oftruncate_args *uap;
1601 	int *retval;
1602 {
1603 	struct ftruncate_args nuap;
1604 
1605 	nuap.fd = uap->fd;
1606 	nuap.length = uap->length;
1607 	return (ftruncate(p, &nuap, retval));
1608 }
1609 #endif /* COMPAT_43 || COMPAT_SUNOS */
1610 
1611 /*
1612  * Sync an open file.
1613  */
1614 struct fsync_args {
1615 	int	fd;
1616 };
1617 /* ARGSUSED */
1618 fsync(p, uap, retval)
1619 	struct proc *p;
1620 	struct fsync_args *uap;
1621 	int *retval;
1622 {
1623 	register struct vnode *vp;
1624 	struct file *fp;
1625 	int error;
1626 
1627 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1628 		return (error);
1629 	vp = (struct vnode *)fp->f_data;
1630 	VOP_LOCK(vp);
1631 	error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p);
1632 	VOP_UNLOCK(vp);
1633 	return (error);
1634 }
1635 
1636 /*
1637  * Rename files.  Source and destination must either both be directories,
1638  * or both not be directories.  If target is a directory, it must be empty.
1639  */
1640 struct rename_args {
1641 	char	*from;
1642 	char	*to;
1643 };
1644 /* ARGSUSED */
1645 rename(p, uap, retval)
1646 	struct proc *p;
1647 	register struct rename_args *uap;
1648 	int *retval;
1649 {
1650 	register struct vnode *tvp, *fvp, *tdvp;
1651 	struct nameidata fromnd, tond;
1652 	int error;
1653 
1654 	NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE,
1655 		uap->from, p);
1656 	if (error = namei(&fromnd))
1657 		return (error);
1658 	fvp = fromnd.ni_vp;
1659 	NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART,
1660 		UIO_USERSPACE, uap->to, p);
1661 	if (error = namei(&tond)) {
1662 		VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
1663 		vrele(fromnd.ni_dvp);
1664 		vrele(fvp);
1665 		goto out1;
1666 	}
1667 	tdvp = tond.ni_dvp;
1668 	tvp = tond.ni_vp;
1669 	if (tvp != NULL) {
1670 		if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
1671 			error = ENOTDIR;
1672 			goto out;
1673 		} else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
1674 			error = EISDIR;
1675 			goto out;
1676 		}
1677 	}
1678 	if (fvp == tdvp)
1679 		error = EINVAL;
1680 	/*
1681 	 * If source is the same as the destination (that is the
1682 	 * same inode number with the same name in the same directory),
1683 	 * then there is nothing to do.
1684 	 */
1685 	if (fvp == tvp && fromnd.ni_dvp == tdvp &&
1686 	    fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen &&
1687 	    !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr,
1688 	      fromnd.ni_cnd.cn_namelen))
1689 		error = -1;
1690 out:
1691 	if (!error) {
1692 		LEASE_CHECK(tdvp, p, p->p_ucred, LEASE_WRITE);
1693 		if (fromnd.ni_dvp != tdvp)
1694 			LEASE_CHECK(fromnd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
1695 		if (tvp)
1696 			LEASE_CHECK(tvp, p, p->p_ucred, LEASE_WRITE);
1697 		error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
1698 				   tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
1699 	} else {
1700 		VOP_ABORTOP(tond.ni_dvp, &tond.ni_cnd);
1701 		if (tdvp == tvp)
1702 			vrele(tdvp);
1703 		else
1704 			vput(tdvp);
1705 		if (tvp)
1706 			vput(tvp);
1707 		VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
1708 		vrele(fromnd.ni_dvp);
1709 		vrele(fvp);
1710 	}
1711 	vrele(tond.ni_startdir);
1712 	FREE(tond.ni_cnd.cn_pnbuf, M_NAMEI);
1713 out1:
1714 	vrele(fromnd.ni_startdir);
1715 	FREE(fromnd.ni_cnd.cn_pnbuf, M_NAMEI);
1716 	if (error == -1)
1717 		return (0);
1718 	return (error);
1719 }
1720 
1721 /*
1722  * Make a directory file.
1723  */
1724 struct mkdir_args {
1725 	char	*path;
1726 	int	mode;
1727 };
1728 /* ARGSUSED */
1729 mkdir(p, uap, retval)
1730 	struct proc *p;
1731 	register struct mkdir_args *uap;
1732 	int *retval;
1733 {
1734 	register struct vnode *vp;
1735 	struct vattr vattr;
1736 	int error;
1737 	struct nameidata nd;
1738 
1739 	NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->path, p);
1740 	if (error = namei(&nd))
1741 		return (error);
1742 	vp = nd.ni_vp;
1743 	if (vp != NULL) {
1744 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1745 		if (nd.ni_dvp == vp)
1746 			vrele(nd.ni_dvp);
1747 		else
1748 			vput(nd.ni_dvp);
1749 		vrele(vp);
1750 		return (EEXIST);
1751 	}
1752 	VATTR_NULL(&vattr);
1753 	vattr.va_type = VDIR;
1754 	vattr.va_mode = (uap->mode & ACCESSPERMS) &~ p->p_fd->fd_cmask;
1755 	LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
1756 	error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
1757 	if (!error)
1758 		vput(nd.ni_vp);
1759 	return (error);
1760 }
1761 
1762 /*
1763  * Remove a directory file.
1764  */
1765 struct rmdir_args {
1766 	char	*path;
1767 };
1768 /* ARGSUSED */
1769 rmdir(p, uap, retval)
1770 	struct proc *p;
1771 	struct rmdir_args *uap;
1772 	int *retval;
1773 {
1774 	register struct vnode *vp;
1775 	int error;
1776 	struct nameidata nd;
1777 
1778 	NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE, uap->path, p);
1779 	if (error = namei(&nd))
1780 		return (error);
1781 	vp = nd.ni_vp;
1782 	if (vp->v_type != VDIR) {
1783 		error = ENOTDIR;
1784 		goto out;
1785 	}
1786 	/*
1787 	 * No rmdir "." please.
1788 	 */
1789 	if (nd.ni_dvp == vp) {
1790 		error = EINVAL;
1791 		goto out;
1792 	}
1793 	/*
1794 	 * The root of a mounted filesystem cannot be deleted.
1795 	 */
1796 	if (vp->v_flag & VROOT)
1797 		error = EBUSY;
1798 out:
1799 	if (!error) {
1800 		LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
1801 		LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1802 		error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
1803 	} else {
1804 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1805 		if (nd.ni_dvp == vp)
1806 			vrele(nd.ni_dvp);
1807 		else
1808 			vput(nd.ni_dvp);
1809 		vput(vp);
1810 	}
1811 	return (error);
1812 }
1813 
1814 #ifdef COMPAT_43
1815 /*
1816  * Read a block of directory entries in a file system independent format.
1817  */
1818 struct ogetdirentries_args {
1819 	int	fd;
1820 	char	*buf;
1821 	u_int	count;
1822 	long	*basep;
1823 };
1824 ogetdirentries(p, uap, retval)
1825 	struct proc *p;
1826 	register struct ogetdirentries_args *uap;
1827 	int *retval;
1828 {
1829 	register struct vnode *vp;
1830 	struct file *fp;
1831 	struct uio auio, kuio;
1832 	struct iovec aiov, kiov;
1833 	struct dirent *dp, *edp;
1834 	caddr_t dirbuf;
1835 	int error, readcnt;
1836 	long loff;
1837 
1838 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1839 		return (error);
1840 	if ((fp->f_flag & FREAD) == 0)
1841 		return (EBADF);
1842 	vp = (struct vnode *)fp->f_data;
1843 	if (vp->v_type != VDIR)
1844 		return (EINVAL);
1845 	aiov.iov_base = uap->buf;
1846 	aiov.iov_len = uap->count;
1847 	auio.uio_iov = &aiov;
1848 	auio.uio_iovcnt = 1;
1849 	auio.uio_rw = UIO_READ;
1850 	auio.uio_segflg = UIO_USERSPACE;
1851 	auio.uio_procp = p;
1852 	auio.uio_resid = uap->count;
1853 	VOP_LOCK(vp);
1854 	loff = auio.uio_offset = fp->f_offset;
1855 #	if (BYTE_ORDER != LITTLE_ENDIAN)
1856 		if (vp->v_mount->mnt_maxsymlinklen <= 0) {
1857 			error = VOP_READDIR(vp, &auio, fp->f_cred);
1858 			fp->f_offset = auio.uio_offset;
1859 		} else
1860 #	endif
1861 	{
1862 		kuio = auio;
1863 		kuio.uio_iov = &kiov;
1864 		kuio.uio_segflg = UIO_SYSSPACE;
1865 		kiov.iov_len = uap->count;
1866 		MALLOC(dirbuf, caddr_t, uap->count, M_TEMP, M_WAITOK);
1867 		kiov.iov_base = dirbuf;
1868 		error = VOP_READDIR(vp, &kuio, fp->f_cred);
1869 		fp->f_offset = kuio.uio_offset;
1870 		if (error == 0) {
1871 			readcnt = uap->count - kuio.uio_resid;
1872 			edp = (struct dirent *)&dirbuf[readcnt];
1873 			for (dp = (struct dirent *)dirbuf; dp < edp; ) {
1874 #				if (BYTE_ORDER == LITTLE_ENDIAN)
1875 					/*
1876 					 * The expected low byte of
1877 					 * dp->d_namlen is our dp->d_type.
1878 					 * The high MBZ byte of dp->d_namlen
1879 					 * is our dp->d_namlen.
1880 					 */
1881 					dp->d_type = dp->d_namlen;
1882 					dp->d_namlen = 0;
1883 #				else
1884 					/*
1885 					 * The dp->d_type is the high byte
1886 					 * of the expected dp->d_namlen,
1887 					 * so must be zero'ed.
1888 					 */
1889 					dp->d_type = 0;
1890 #				endif
1891 				if (dp->d_reclen > 0) {
1892 					dp = (struct dirent *)
1893 					    ((char *)dp + dp->d_reclen);
1894 				} else {
1895 					error = EIO;
1896 					break;
1897 				}
1898 			}
1899 			if (dp >= edp)
1900 				error = uiomove(dirbuf, readcnt, &auio);
1901 		}
1902 		FREE(dirbuf, M_TEMP);
1903 	}
1904 	VOP_UNLOCK(vp);
1905 	if (error)
1906 		return (error);
1907 	error = copyout((caddr_t)&loff, (caddr_t)uap->basep, sizeof(long));
1908 	*retval = uap->count - auio.uio_resid;
1909 	return (error);
1910 }
1911 #endif
1912 
1913 /*
1914  * Read a block of directory entries in a file system independent format.
1915  */
1916 struct getdirentries_args {
1917 	int	fd;
1918 	char	*buf;
1919 	u_int	count;
1920 	long	*basep;
1921 };
1922 getdirentries(p, uap, retval)
1923 	struct proc *p;
1924 	register struct getdirentries_args *uap;
1925 	int *retval;
1926 {
1927 	register struct vnode *vp;
1928 	struct file *fp;
1929 	struct uio auio;
1930 	struct iovec aiov;
1931 	long loff;
1932 	int error;
1933 
1934 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1935 		return (error);
1936 	if ((fp->f_flag & FREAD) == 0)
1937 		return (EBADF);
1938 	vp = (struct vnode *)fp->f_data;
1939 unionread:
1940 	if (vp->v_type != VDIR)
1941 		return (EINVAL);
1942 	aiov.iov_base = uap->buf;
1943 	aiov.iov_len = uap->count;
1944 	auio.uio_iov = &aiov;
1945 	auio.uio_iovcnt = 1;
1946 	auio.uio_rw = UIO_READ;
1947 	auio.uio_segflg = UIO_USERSPACE;
1948 	auio.uio_procp = p;
1949 	auio.uio_resid = uap->count;
1950 	VOP_LOCK(vp);
1951 	loff = auio.uio_offset = fp->f_offset;
1952 	error = VOP_READDIR(vp, &auio, fp->f_cred);
1953 	fp->f_offset = auio.uio_offset;
1954 	VOP_UNLOCK(vp);
1955 	if (error)
1956 		return (error);
1957 	if ((uap->count == auio.uio_resid) &&
1958 	    (vp->v_flag & VROOT) &&
1959 	    (vp->v_mount->mnt_flag & MNT_UNION)) {
1960 		struct vnode *tvp = vp;
1961 		vp = vp->v_mount->mnt_vnodecovered;
1962 		VREF(vp);
1963 		fp->f_data = (caddr_t) vp;
1964 		fp->f_offset = 0;
1965 		vrele(tvp);
1966 		goto unionread;
1967 	}
1968 	error = copyout((caddr_t)&loff, (caddr_t)uap->basep, sizeof(long));
1969 	*retval = uap->count - auio.uio_resid;
1970 	return (error);
1971 }
1972 
1973 /*
1974  * Set the mode mask for creation of filesystem nodes.
1975  */
1976 struct umask_args {
1977 	int	newmask;
1978 };
1979 mode_t				/* XXX */
1980 umask(p, uap, retval)
1981 	struct proc *p;
1982 	struct umask_args *uap;
1983 	int *retval;
1984 {
1985 	register struct filedesc *fdp;
1986 
1987 	fdp = p->p_fd;
1988 	*retval = fdp->fd_cmask;
1989 	fdp->fd_cmask = uap->newmask & ALLPERMS;
1990 	return (0);
1991 }
1992 
1993 /*
1994  * Void all references to file by ripping underlying filesystem
1995  * away from vnode.
1996  */
1997 struct revoke_args {
1998 	char	*path;
1999 };
2000 /* ARGSUSED */
2001 revoke(p, uap, retval)
2002 	struct proc *p;
2003 	register struct revoke_args *uap;
2004 	int *retval;
2005 {
2006 	register struct vnode *vp;
2007 	struct vattr vattr;
2008 	int error;
2009 	struct nameidata nd;
2010 
2011 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path, p);
2012 	if (error = namei(&nd))
2013 		return (error);
2014 	vp = nd.ni_vp;
2015 	if (vp->v_type != VCHR && vp->v_type != VBLK) {
2016 		error = EINVAL;
2017 		goto out;
2018 	}
2019 	if (error = VOP_GETATTR(vp, &vattr, p->p_ucred, p))
2020 		goto out;
2021 	if (p->p_ucred->cr_uid != vattr.va_uid &&
2022 	    (error = suser(p->p_ucred, &p->p_acflag)))
2023 		goto out;
2024 	if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
2025 		vgoneall(vp);
2026 out:
2027 	vrele(vp);
2028 	return (error);
2029 }
2030 
2031 /*
2032  * Convert a user file descriptor to a kernel file entry.
2033  */
2034 getvnode(fdp, fd, fpp)
2035 	struct filedesc *fdp;
2036 	struct file **fpp;
2037 	int fd;
2038 {
2039 	struct file *fp;
2040 
2041 	if ((u_int)fd >= fdp->fd_nfiles ||
2042 	    (fp = fdp->fd_ofiles[fd]) == NULL)
2043 		return (EBADF);
2044 	if (fp->f_type != DTYPE_VNODE)
2045 		return (EINVAL);
2046 	*fpp = fp;
2047 	return (0);
2048 }
2049