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