xref: /original-bsd/sys/kern/vfs_syscalls.c (revision 3705696b)
1 /*
2  * Copyright (c) 1989, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)vfs_syscalls.c	8.1 (Berkeley) 06/14/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 access_args {
961 	char	*fname;
962 	int	fmode;
963 };
964 access(p, uap, retval)
965 	struct proc *p;
966 	register struct access_args *uap;
967 	int *retval;
968 {
969 	register struct ucred *cred = p->p_ucred;
970 	register struct vnode *vp;
971 	int error, mode, svuid, svgid;
972 	struct nameidata nd;
973 
974 	svuid = cred->cr_uid;
975 	svgid = cred->cr_groups[0];
976 	cred->cr_uid = p->p_cred->p_ruid;
977 	cred->cr_groups[0] = p->p_cred->p_rgid;
978 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p);
979 	if (error = namei(&nd))
980 		goto out1;
981 	vp = nd.ni_vp;
982 	/*
983 	 * fmode == 0 means only check for exist
984 	 */
985 	if (uap->fmode) {
986 		mode = 0;
987 		if (uap->fmode & R_OK)
988 			mode |= VREAD;
989 		if (uap->fmode & W_OK)
990 			mode |= VWRITE;
991 		if (uap->fmode & X_OK)
992 			mode |= VEXEC;
993 		if ((mode & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
994 			error = VOP_ACCESS(vp, mode, cred, p);
995 	}
996 	vput(vp);
997 out1:
998 	cred->cr_uid = svuid;
999 	cred->cr_groups[0] = svgid;
1000 	return (error);
1001 }
1002 
1003 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1004 /*
1005  * Stat system call.
1006  * This version follows links.
1007  */
1008 struct ostat_args {
1009 	char	*fname;
1010 	struct ostat *ub;
1011 };
1012 /* ARGSUSED */
1013 ostat(p, uap, retval)
1014 	struct proc *p;
1015 	register struct ostat_args *uap;
1016 	int *retval;
1017 {
1018 	struct stat sb;
1019 	struct ostat osb;
1020 	int error;
1021 	struct nameidata nd;
1022 
1023 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p);
1024 	if (error = namei(&nd))
1025 		return (error);
1026 	error = vn_stat(nd.ni_vp, &sb, p);
1027 	vput(nd.ni_vp);
1028 	if (error)
1029 		return (error);
1030 	cvtstat(&sb, &osb);
1031 	error = copyout((caddr_t)&osb, (caddr_t)uap->ub, sizeof (osb));
1032 	return (error);
1033 }
1034 
1035 /*
1036  * Lstat system call.
1037  * This version does not follow links.
1038  */
1039 struct olstat_args {
1040 	char	*fname;
1041 	struct ostat *ub;
1042 };
1043 /* ARGSUSED */
1044 olstat(p, uap, retval)
1045 	struct proc *p;
1046 	register struct olstat_args *uap;
1047 	int *retval;
1048 {
1049 	struct stat sb;
1050 	struct ostat osb;
1051 	int error;
1052 	struct nameidata nd;
1053 
1054 	NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p);
1055 	if (error = namei(&nd))
1056 		return (error);
1057 	error = vn_stat(nd.ni_vp, &sb, p);
1058 	vput(nd.ni_vp);
1059 	if (error)
1060 		return (error);
1061 	cvtstat(&sb, &osb);
1062 	error = copyout((caddr_t)&osb, (caddr_t)uap->ub, sizeof (osb));
1063 	return (error);
1064 }
1065 
1066 /*
1067  * convert from an old to a new stat structure.
1068  */
1069 cvtstat(st, ost)
1070 	struct stat *st;
1071 	struct ostat *ost;
1072 {
1073 
1074 	ost->st_dev = st->st_dev;
1075 	ost->st_ino = st->st_ino;
1076 	ost->st_mode = st->st_mode;
1077 	ost->st_nlink = st->st_nlink;
1078 	ost->st_uid = st->st_uid;
1079 	ost->st_gid = st->st_gid;
1080 	ost->st_rdev = st->st_rdev;
1081 	if (st->st_size < (quad_t)1 << 32)
1082 		ost->st_size = st->st_size;
1083 	else
1084 		ost->st_size = -2;
1085 	ost->st_atime = st->st_atime;
1086 	ost->st_mtime = st->st_mtime;
1087 	ost->st_ctime = st->st_ctime;
1088 	ost->st_blksize = st->st_blksize;
1089 	ost->st_blocks = st->st_blocks;
1090 	ost->st_flags = st->st_flags;
1091 	ost->st_gen = st->st_gen;
1092 }
1093 #endif /* COMPAT_43 || COMPAT_SUNOS */
1094 
1095 /*
1096  * Stat system call.
1097  * This version follows links.
1098  */
1099 struct stat_args {
1100 	char	*fname;
1101 	struct stat *ub;
1102 };
1103 /* ARGSUSED */
1104 stat(p, uap, retval)
1105 	struct proc *p;
1106 	register struct stat_args *uap;
1107 	int *retval;
1108 {
1109 	struct stat sb;
1110 	int error;
1111 	struct nameidata nd;
1112 
1113 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p);
1114 	if (error = namei(&nd))
1115 		return (error);
1116 	error = vn_stat(nd.ni_vp, &sb, p);
1117 	vput(nd.ni_vp);
1118 	if (error)
1119 		return (error);
1120 	error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
1121 	return (error);
1122 }
1123 
1124 /*
1125  * Lstat system call.
1126  * This version does not follow links.
1127  */
1128 struct lstat_args {
1129 	char	*fname;
1130 	struct stat *ub;
1131 };
1132 /* ARGSUSED */
1133 lstat(p, uap, retval)
1134 	struct proc *p;
1135 	register struct lstat_args *uap;
1136 	int *retval;
1137 {
1138 	int error;
1139 	struct vnode *vp, *dvp;
1140 	struct stat sb, sb1;
1141 	struct nameidata nd;
1142 
1143 	NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKPARENT, UIO_USERSPACE,
1144 	    uap->fname, p);
1145 	if (error = namei(&nd))
1146 		return (error);
1147 	/*
1148 	 * For symbolic links, always return the attributes of its
1149 	 * containing directory, except for mode, size, and links.
1150 	 */
1151 	vp = nd.ni_vp;
1152 	dvp = nd.ni_dvp;
1153 	if (vp->v_type != VLNK) {
1154 		if (dvp == vp)
1155 			vrele(dvp);
1156 		else
1157 			vput(dvp);
1158 		error = vn_stat(vp, &sb, p);
1159 		vput(vp);
1160 		if (error)
1161 			return (error);
1162 	} else {
1163 		error = vn_stat(dvp, &sb, p);
1164 		vput(dvp);
1165 		if (error) {
1166 			vput(vp);
1167 			return (error);
1168 		}
1169 		error = vn_stat(vp, &sb1, p);
1170 		vput(vp);
1171 		if (error)
1172 			return (error);
1173 		sb.st_mode &= ~S_IFDIR;
1174 		sb.st_mode |= S_IFLNK;
1175 		sb.st_nlink = sb1.st_nlink;
1176 		sb.st_size = sb1.st_size;
1177 		sb.st_blocks = sb1.st_blocks;
1178 	}
1179 	error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
1180 	return (error);
1181 }
1182 
1183 /*
1184  * Pathconf system call.
1185  */
1186 struct pathconf_args {
1187 	char	*fname;
1188 	int	name;
1189 };
1190 /* ARGSUSED */
1191 pathconf(p, uap, retval)
1192 	struct proc *p;
1193 	register struct pathconf_args *uap;
1194 	int *retval;
1195 {
1196 	int error;
1197 	struct nameidata nd;
1198 
1199 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, uap->fname, p);
1200 	if (error = namei(&nd))
1201 		return (error);
1202 	error = VOP_PATHCONF(nd.ni_vp, uap->name, retval);
1203 	vput(nd.ni_vp);
1204 	return (error);
1205 }
1206 
1207 /*
1208  * Return target name of a symbolic link.
1209  */
1210 struct readlink_args {
1211 	char	*name;
1212 	char	*buf;
1213 	int	count;
1214 };
1215 /* ARGSUSED */
1216 readlink(p, uap, retval)
1217 	struct proc *p;
1218 	register struct readlink_args *uap;
1219 	int *retval;
1220 {
1221 	register struct vnode *vp;
1222 	struct iovec aiov;
1223 	struct uio auio;
1224 	int error;
1225 	struct nameidata nd;
1226 
1227 	NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE, uap->name, p);
1228 	if (error = namei(&nd))
1229 		return (error);
1230 	vp = nd.ni_vp;
1231 	if (vp->v_type != VLNK) {
1232 		error = EINVAL;
1233 		goto out;
1234 	}
1235 	aiov.iov_base = uap->buf;
1236 	aiov.iov_len = uap->count;
1237 	auio.uio_iov = &aiov;
1238 	auio.uio_iovcnt = 1;
1239 	auio.uio_offset = 0;
1240 	auio.uio_rw = UIO_READ;
1241 	auio.uio_segflg = UIO_USERSPACE;
1242 	auio.uio_procp = p;
1243 	auio.uio_resid = uap->count;
1244 	error = VOP_READLINK(vp, &auio, p->p_ucred);
1245 out:
1246 	vput(vp);
1247 	*retval = uap->count - auio.uio_resid;
1248 	return (error);
1249 }
1250 
1251 /*
1252  * Change flags of a file given path name.
1253  */
1254 struct chflags_args {
1255 	char	*fname;
1256 	int	flags;
1257 };
1258 /* ARGSUSED */
1259 chflags(p, uap, retval)
1260 	struct proc *p;
1261 	register struct chflags_args *uap;
1262 	int *retval;
1263 {
1264 	register struct vnode *vp;
1265 	struct vattr vattr;
1266 	int error;
1267 	struct nameidata nd;
1268 
1269 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p);
1270 	if (error = namei(&nd))
1271 		return (error);
1272 	vp = nd.ni_vp;
1273 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1274 	VOP_LOCK(vp);
1275 	if (vp->v_mount->mnt_flag & MNT_RDONLY) {
1276 		error = EROFS;
1277 		goto out;
1278 	}
1279 	VATTR_NULL(&vattr);
1280 	vattr.va_flags = uap->flags;
1281 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1282 out:
1283 	vput(vp);
1284 	return (error);
1285 }
1286 
1287 /*
1288  * Change flags of a file given a file descriptor.
1289  */
1290 struct fchflags_args {
1291 	int	fd;
1292 	int	flags;
1293 };
1294 /* ARGSUSED */
1295 fchflags(p, uap, retval)
1296 	struct proc *p;
1297 	register struct fchflags_args *uap;
1298 	int *retval;
1299 {
1300 	struct vattr vattr;
1301 	struct vnode *vp;
1302 	struct file *fp;
1303 	int error;
1304 
1305 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1306 		return (error);
1307 	vp = (struct vnode *)fp->f_data;
1308 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1309 	VOP_LOCK(vp);
1310 	if (vp->v_mount->mnt_flag & MNT_RDONLY) {
1311 		error = EROFS;
1312 		goto out;
1313 	}
1314 	VATTR_NULL(&vattr);
1315 	vattr.va_flags = uap->flags;
1316 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1317 out:
1318 	VOP_UNLOCK(vp);
1319 	return (error);
1320 }
1321 
1322 /*
1323  * Change mode of a file given path name.
1324  */
1325 struct chmod_args {
1326 	char	*fname;
1327 	int	fmode;
1328 };
1329 /* ARGSUSED */
1330 chmod(p, uap, retval)
1331 	struct proc *p;
1332 	register struct chmod_args *uap;
1333 	int *retval;
1334 {
1335 	register struct vnode *vp;
1336 	struct vattr vattr;
1337 	int error;
1338 	struct nameidata nd;
1339 
1340 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p);
1341 	if (error = namei(&nd))
1342 		return (error);
1343 	vp = nd.ni_vp;
1344 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1345 	VOP_LOCK(vp);
1346 	if (vp->v_mount->mnt_flag & MNT_RDONLY) {
1347 		error = EROFS;
1348 		goto out;
1349 	}
1350 	VATTR_NULL(&vattr);
1351 	vattr.va_mode = uap->fmode & 07777;
1352 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1353 out:
1354 	vput(vp);
1355 	return (error);
1356 }
1357 
1358 /*
1359  * Change mode of a file given a file descriptor.
1360  */
1361 struct fchmod_args {
1362 	int	fd;
1363 	int	fmode;
1364 };
1365 /* ARGSUSED */
1366 fchmod(p, uap, retval)
1367 	struct proc *p;
1368 	register struct fchmod_args *uap;
1369 	int *retval;
1370 {
1371 	struct vattr vattr;
1372 	struct vnode *vp;
1373 	struct file *fp;
1374 	int error;
1375 
1376 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1377 		return (error);
1378 	vp = (struct vnode *)fp->f_data;
1379 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1380 	VOP_LOCK(vp);
1381 	if (vp->v_mount->mnt_flag & MNT_RDONLY) {
1382 		error = EROFS;
1383 		goto out;
1384 	}
1385 	VATTR_NULL(&vattr);
1386 	vattr.va_mode = uap->fmode & 07777;
1387 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1388 out:
1389 	VOP_UNLOCK(vp);
1390 	return (error);
1391 }
1392 
1393 /*
1394  * Set ownership given a path name.
1395  */
1396 struct chown_args {
1397 	char	*fname;
1398 	int	uid;
1399 	int	gid;
1400 };
1401 /* ARGSUSED */
1402 chown(p, uap, retval)
1403 	struct proc *p;
1404 	register struct chown_args *uap;
1405 	int *retval;
1406 {
1407 	register struct vnode *vp;
1408 	struct vattr vattr;
1409 	int error;
1410 	struct nameidata nd;
1411 
1412 	NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->fname, p);
1413 	if (error = namei(&nd))
1414 		return (error);
1415 	vp = nd.ni_vp;
1416 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1417 	VOP_LOCK(vp);
1418 	if (vp->v_mount->mnt_flag & MNT_RDONLY) {
1419 		error = EROFS;
1420 		goto out;
1421 	}
1422 	VATTR_NULL(&vattr);
1423 	vattr.va_uid = uap->uid;
1424 	vattr.va_gid = uap->gid;
1425 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1426 out:
1427 	vput(vp);
1428 	return (error);
1429 }
1430 
1431 /*
1432  * Set ownership given a file descriptor.
1433  */
1434 struct fchown_args {
1435 	int	fd;
1436 	int	uid;
1437 	int	gid;
1438 };
1439 /* ARGSUSED */
1440 fchown(p, uap, retval)
1441 	struct proc *p;
1442 	register struct fchown_args *uap;
1443 	int *retval;
1444 {
1445 	struct vattr vattr;
1446 	struct vnode *vp;
1447 	struct file *fp;
1448 	int error;
1449 
1450 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1451 		return (error);
1452 	vp = (struct vnode *)fp->f_data;
1453 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1454 	VOP_LOCK(vp);
1455 	if (vp->v_mount->mnt_flag & MNT_RDONLY) {
1456 		error = EROFS;
1457 		goto out;
1458 	}
1459 	VATTR_NULL(&vattr);
1460 	vattr.va_uid = uap->uid;
1461 	vattr.va_gid = uap->gid;
1462 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1463 out:
1464 	VOP_UNLOCK(vp);
1465 	return (error);
1466 }
1467 
1468 /*
1469  * Set the access and modification times of a file.
1470  */
1471 struct utimes_args {
1472 	char	*fname;
1473 	struct	timeval *tptr;
1474 };
1475 /* ARGSUSED */
1476 utimes(p, uap, retval)
1477 	struct proc *p;
1478 	register struct utimes_args *uap;
1479 	int *retval;
1480 {
1481 	register struct vnode *vp;
1482 	struct timeval tv[2];
1483 	struct vattr vattr;
1484 	int error;
1485 	struct nameidata nd;
1486 
1487 	VATTR_NULL(&vattr);
1488 	if (uap->tptr == NULL) {
1489 		microtime(&tv[0]);
1490 		tv[1] = tv[0];
1491 		vattr.va_vaflags |= VA_UTIMES_NULL;
1492 	} else if (error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)))
1493   		return (error);
1494 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p);
1495 	if (error = namei(&nd))
1496 		return (error);
1497 	vp = nd.ni_vp;
1498 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1499 	VOP_LOCK(vp);
1500 	if (vp->v_mount->mnt_flag & MNT_RDONLY) {
1501 		error = EROFS;
1502 		goto out;
1503 	}
1504 	vattr.va_atime.ts_sec = tv[0].tv_sec;
1505 	vattr.va_atime.ts_nsec = tv[0].tv_usec * 1000;
1506 	vattr.va_mtime.ts_sec = tv[1].tv_sec;
1507 	vattr.va_mtime.ts_nsec = tv[1].tv_usec * 1000;
1508 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1509 out:
1510 	vput(vp);
1511 	return (error);
1512 }
1513 
1514 struct truncate_args {
1515 	char	*fname;
1516 	int	pad;
1517 	off_t	length;
1518 };
1519 
1520 /*
1521  * Truncate a file given its path name.
1522  */
1523 /* ARGSUSED */
1524 truncate(p, uap, retval)
1525 	struct proc *p;
1526 	register struct truncate_args *uap;
1527 	int *retval;
1528 {
1529 	register struct vnode *vp;
1530 	struct vattr vattr;
1531 	int error;
1532 	struct nameidata nd;
1533 
1534 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p);
1535 	if (error = namei(&nd))
1536 		return (error);
1537 	vp = nd.ni_vp;
1538 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1539 	VOP_LOCK(vp);
1540 	if (vp->v_type == VDIR) {
1541 		error = EISDIR;
1542 		goto out;
1543 	}
1544 	if ((error = vn_writechk(vp)) ||
1545 	    (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, p)))
1546 		goto out;
1547 	VATTR_NULL(&vattr);
1548 	vattr.va_size = uap->length;
1549 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1550 out:
1551 	vput(vp);
1552 	return (error);
1553 }
1554 
1555 struct ftruncate_args {
1556 	int	fd;
1557 	int	pad;
1558 	off_t	length;
1559 };
1560 
1561 /*
1562  * Truncate a file given a file descriptor.
1563  */
1564 /* ARGSUSED */
1565 ftruncate(p, uap, retval)
1566 	struct proc *p;
1567 	register struct ftruncate_args *uap;
1568 	int *retval;
1569 {
1570 	struct vattr vattr;
1571 	struct vnode *vp;
1572 	struct file *fp;
1573 	int error;
1574 
1575 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1576 		return (error);
1577 	if ((fp->f_flag & FWRITE) == 0)
1578 		return (EINVAL);
1579 	vp = (struct vnode *)fp->f_data;
1580 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1581 	VOP_LOCK(vp);
1582 	if (vp->v_type == VDIR) {
1583 		error = EISDIR;
1584 		goto out;
1585 	}
1586 	if (error = vn_writechk(vp))
1587 		goto out;
1588 	VATTR_NULL(&vattr);
1589 	vattr.va_size = uap->length;
1590 	error = VOP_SETATTR(vp, &vattr, fp->f_cred, p);
1591 out:
1592 	VOP_UNLOCK(vp);
1593 	return (error);
1594 }
1595 
1596 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1597 /*
1598  * Truncate a file given its path name.
1599  */
1600 struct otruncate_args {
1601 	char	*fname;
1602 	long	length;
1603 };
1604 /* ARGSUSED */
1605 otruncate(p, uap, retval)
1606 	struct proc *p;
1607 	register struct otruncate_args *uap;
1608 	int *retval;
1609 {
1610 	struct truncate_args nuap;
1611 
1612 	nuap.fname = uap->fname;
1613 	nuap.length = uap->length;
1614 	return (truncate(p, &nuap, retval));
1615 }
1616 
1617 /*
1618  * Truncate a file given a file descriptor.
1619  */
1620 struct oftruncate_args {
1621 	int	fd;
1622 	long	length;
1623 };
1624 /* ARGSUSED */
1625 oftruncate(p, uap, retval)
1626 	struct proc *p;
1627 	register struct oftruncate_args *uap;
1628 	int *retval;
1629 {
1630 	struct ftruncate_args nuap;
1631 
1632 	nuap.fd = uap->fd;
1633 	nuap.length = uap->length;
1634 	return (ftruncate(p, &nuap, retval));
1635 }
1636 #endif /* COMPAT_43 || COMPAT_SUNOS */
1637 
1638 /*
1639  * Synch an open file.
1640  */
1641 struct fsync_args {
1642 	int	fd;
1643 };
1644 /* ARGSUSED */
1645 fsync(p, uap, retval)
1646 	struct proc *p;
1647 	struct fsync_args *uap;
1648 	int *retval;
1649 {
1650 	register struct vnode *vp;
1651 	struct file *fp;
1652 	int error;
1653 
1654 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1655 		return (error);
1656 	vp = (struct vnode *)fp->f_data;
1657 	VOP_LOCK(vp);
1658 	error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p);
1659 	VOP_UNLOCK(vp);
1660 	return (error);
1661 }
1662 
1663 /*
1664  * Rename system call.
1665  *
1666  * Source and destination must either both be directories, or both
1667  * not be directories.  If target is a directory, it must be empty.
1668  */
1669 struct rename_args {
1670 	char	*from;
1671 	char	*to;
1672 };
1673 /* ARGSUSED */
1674 rename(p, uap, retval)
1675 	struct proc *p;
1676 	register struct rename_args *uap;
1677 	int *retval;
1678 {
1679 	register struct vnode *tvp, *fvp, *tdvp;
1680 	struct nameidata fromnd, tond;
1681 	int error;
1682 
1683 	NDINIT(&fromnd, DELETE, WANTPARENT | SAVESTART, UIO_USERSPACE,
1684 		uap->from, p);
1685 	if (error = namei(&fromnd))
1686 		return (error);
1687 	fvp = fromnd.ni_vp;
1688 	NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART,
1689 		UIO_USERSPACE, uap->to, p);
1690 	if (error = namei(&tond)) {
1691 		VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
1692 		vrele(fromnd.ni_dvp);
1693 		vrele(fvp);
1694 		goto out1;
1695 	}
1696 	tdvp = tond.ni_dvp;
1697 	tvp = tond.ni_vp;
1698 	if (tvp != NULL) {
1699 		if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
1700 			error = ENOTDIR;
1701 			goto out;
1702 		} else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
1703 			error = EISDIR;
1704 			goto out;
1705 		}
1706 	}
1707 	if (fvp == tdvp)
1708 		error = EINVAL;
1709 	/*
1710 	 * If source is the same as the destination (that is the
1711 	 * same inode number with the same name in the same directory),
1712 	 * then there is nothing to do.
1713 	 */
1714 	if (fvp == tvp && fromnd.ni_dvp == tdvp &&
1715 	    fromnd.ni_cnd.cn_namelen == tond.ni_cnd.cn_namelen &&
1716 	    !bcmp(fromnd.ni_cnd.cn_nameptr, tond.ni_cnd.cn_nameptr,
1717 	      fromnd.ni_cnd.cn_namelen))
1718 		error = -1;
1719 out:
1720 	if (!error) {
1721 		LEASE_CHECK(tdvp, p, p->p_ucred, LEASE_WRITE);
1722 		if (fromnd.ni_dvp != tdvp)
1723 			LEASE_CHECK(fromnd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
1724 		if (tvp)
1725 			LEASE_CHECK(tvp, p, p->p_ucred, LEASE_WRITE);
1726 		error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
1727 				   tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
1728 	} else {
1729 		VOP_ABORTOP(tond.ni_dvp, &tond.ni_cnd);
1730 		if (tdvp == tvp)
1731 			vrele(tdvp);
1732 		else
1733 			vput(tdvp);
1734 		if (tvp)
1735 			vput(tvp);
1736 		VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
1737 		vrele(fromnd.ni_dvp);
1738 		vrele(fvp);
1739 	}
1740 	vrele(tond.ni_startdir);
1741 	FREE(tond.ni_cnd.cn_pnbuf, M_NAMEI);
1742 out1:
1743 	vrele(fromnd.ni_startdir);
1744 	FREE(fromnd.ni_cnd.cn_pnbuf, M_NAMEI);
1745 	if (error == -1)
1746 		return (0);
1747 	return (error);
1748 }
1749 
1750 /*
1751  * Mkdir system call.
1752  */
1753 struct mkdir_args {
1754 	char	*name;
1755 	int	dmode;
1756 };
1757 /* ARGSUSED */
1758 mkdir(p, uap, retval)
1759 	struct proc *p;
1760 	register struct mkdir_args *uap;
1761 	int *retval;
1762 {
1763 	register struct vnode *vp;
1764 	struct vattr vattr;
1765 	int error;
1766 	struct nameidata nd;
1767 
1768 	NDINIT(&nd, CREATE, LOCKPARENT, UIO_USERSPACE, uap->name, p);
1769 	if (error = namei(&nd))
1770 		return (error);
1771 	vp = nd.ni_vp;
1772 	if (vp != NULL) {
1773 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1774 		if (nd.ni_dvp == vp)
1775 			vrele(nd.ni_dvp);
1776 		else
1777 			vput(nd.ni_dvp);
1778 		vrele(vp);
1779 		return (EEXIST);
1780 	}
1781 	VATTR_NULL(&vattr);
1782 	vattr.va_type = VDIR;
1783 	vattr.va_mode = (uap->dmode & 0777) &~ p->p_fd->fd_cmask;
1784 	LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
1785 	error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
1786 	if (!error)
1787 		vput(nd.ni_vp);
1788 	return (error);
1789 }
1790 
1791 /*
1792  * Rmdir system call.
1793  */
1794 struct rmdir_args {
1795 	char	*name;
1796 };
1797 /* ARGSUSED */
1798 rmdir(p, uap, retval)
1799 	struct proc *p;
1800 	struct rmdir_args *uap;
1801 	int *retval;
1802 {
1803 	register struct vnode *vp;
1804 	int error;
1805 	struct nameidata nd;
1806 
1807 	NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE, uap->name, p);
1808 	if (error = namei(&nd))
1809 		return (error);
1810 	vp = nd.ni_vp;
1811 	if (vp->v_type != VDIR) {
1812 		error = ENOTDIR;
1813 		goto out;
1814 	}
1815 	/*
1816 	 * No rmdir "." please.
1817 	 */
1818 	if (nd.ni_dvp == vp) {
1819 		error = EINVAL;
1820 		goto out;
1821 	}
1822 	/*
1823 	 * The root of a mounted filesystem cannot be deleted.
1824 	 */
1825 	if (vp->v_flag & VROOT)
1826 		error = EBUSY;
1827 out:
1828 	if (!error) {
1829 		LEASE_CHECK(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
1830 		LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1831 		error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
1832 	} else {
1833 		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
1834 		if (nd.ni_dvp == vp)
1835 			vrele(nd.ni_dvp);
1836 		else
1837 			vput(nd.ni_dvp);
1838 		vput(vp);
1839 	}
1840 	return (error);
1841 }
1842 
1843 #ifdef COMPAT_43
1844 /*
1845  * Read a block of directory entries in a file system independent format.
1846  */
1847 struct ogetdirentries_args {
1848 	int	fd;
1849 	char	*buf;
1850 	unsigned count;
1851 	long	*basep;
1852 };
1853 ogetdirentries(p, uap, retval)
1854 	struct proc *p;
1855 	register struct ogetdirentries_args *uap;
1856 	int *retval;
1857 {
1858 	register struct vnode *vp;
1859 	struct file *fp;
1860 	struct uio auio, kuio;
1861 	struct iovec aiov, kiov;
1862 	struct dirent *dp, *edp;
1863 	caddr_t dirbuf;
1864 	int error, readcnt;
1865 	long loff;
1866 
1867 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1868 		return (error);
1869 	if ((fp->f_flag & FREAD) == 0)
1870 		return (EBADF);
1871 	vp = (struct vnode *)fp->f_data;
1872 	if (vp->v_type != VDIR)
1873 		return (EINVAL);
1874 	aiov.iov_base = uap->buf;
1875 	aiov.iov_len = uap->count;
1876 	auio.uio_iov = &aiov;
1877 	auio.uio_iovcnt = 1;
1878 	auio.uio_rw = UIO_READ;
1879 	auio.uio_segflg = UIO_USERSPACE;
1880 	auio.uio_procp = p;
1881 	auio.uio_resid = uap->count;
1882 	VOP_LOCK(vp);
1883 	loff = auio.uio_offset = fp->f_offset;
1884 #	if (BYTE_ORDER != LITTLE_ENDIAN)
1885 		if (vp->v_mount->mnt_maxsymlinklen <= 0) {
1886 			error = VOP_READDIR(vp, &auio, fp->f_cred);
1887 			fp->f_offset = auio.uio_offset;
1888 		} else
1889 #	endif
1890 	{
1891 		kuio = auio;
1892 		kuio.uio_iov = &kiov;
1893 		kuio.uio_segflg = UIO_SYSSPACE;
1894 		kiov.iov_len = uap->count;
1895 		MALLOC(dirbuf, caddr_t, uap->count, M_TEMP, M_WAITOK);
1896 		kiov.iov_base = dirbuf;
1897 		error = VOP_READDIR(vp, &kuio, fp->f_cred);
1898 		fp->f_offset = kuio.uio_offset;
1899 		if (error == 0) {
1900 			readcnt = uap->count - kuio.uio_resid;
1901 			edp = (struct dirent *)&dirbuf[readcnt];
1902 			for (dp = (struct dirent *)dirbuf; dp < edp; ) {
1903 #				if (BYTE_ORDER == LITTLE_ENDIAN)
1904 					/*
1905 					 * The expected low byte of
1906 					 * dp->d_namlen is our dp->d_type.
1907 					 * The high MBZ byte of dp->d_namlen
1908 					 * is our dp->d_namlen.
1909 					 */
1910 					dp->d_type = dp->d_namlen;
1911 					dp->d_namlen = 0;
1912 #				else
1913 					/*
1914 					 * The dp->d_type is the high byte
1915 					 * of the expected dp->d_namlen,
1916 					 * so must be zero'ed.
1917 					 */
1918 					dp->d_type = 0;
1919 #				endif
1920 				if (dp->d_reclen > 0) {
1921 					dp = (struct dirent *)
1922 					    ((char *)dp + dp->d_reclen);
1923 				} else {
1924 					error = EIO;
1925 					break;
1926 				}
1927 			}
1928 			if (dp >= edp)
1929 				error = uiomove(dirbuf, readcnt, &auio);
1930 		}
1931 		FREE(dirbuf, M_TEMP);
1932 	}
1933 	VOP_UNLOCK(vp);
1934 	if (error)
1935 		return (error);
1936 	error = copyout((caddr_t)&loff, (caddr_t)uap->basep, sizeof(long));
1937 	*retval = uap->count - auio.uio_resid;
1938 	return (error);
1939 }
1940 #endif
1941 
1942 /*
1943  * Read a block of directory entries in a file system independent format.
1944  */
1945 struct getdirentries_args {
1946 	int	fd;
1947 	char	*buf;
1948 	unsigned count;
1949 	long	*basep;
1950 };
1951 getdirentries(p, uap, retval)
1952 	struct proc *p;
1953 	register struct getdirentries_args *uap;
1954 	int *retval;
1955 {
1956 	register struct vnode *vp;
1957 	struct file *fp;
1958 	struct uio auio;
1959 	struct iovec aiov;
1960 	long loff;
1961 	int error;
1962 
1963 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1964 		return (error);
1965 	if ((fp->f_flag & FREAD) == 0)
1966 		return (EBADF);
1967 	vp = (struct vnode *)fp->f_data;
1968 unionread:
1969 	if (vp->v_type != VDIR)
1970 		return (EINVAL);
1971 	aiov.iov_base = uap->buf;
1972 	aiov.iov_len = uap->count;
1973 	auio.uio_iov = &aiov;
1974 	auio.uio_iovcnt = 1;
1975 	auio.uio_rw = UIO_READ;
1976 	auio.uio_segflg = UIO_USERSPACE;
1977 	auio.uio_procp = p;
1978 	auio.uio_resid = uap->count;
1979 	VOP_LOCK(vp);
1980 	loff = auio.uio_offset = fp->f_offset;
1981 	error = VOP_READDIR(vp, &auio, fp->f_cred);
1982 	fp->f_offset = auio.uio_offset;
1983 	VOP_UNLOCK(vp);
1984 	if (error)
1985 		return (error);
1986 	if ((uap->count == auio.uio_resid) &&
1987 	    (vp->v_flag & VROOT) &&
1988 	    (vp->v_mount->mnt_flag & MNT_UNION)) {
1989 		struct vnode *tvp = vp;
1990 		vp = vp->v_mount->mnt_vnodecovered;
1991 		VREF(vp);
1992 		fp->f_data = (caddr_t) vp;
1993 		fp->f_offset = 0;
1994 		vrele(tvp);
1995 		goto unionread;
1996 	}
1997 	error = copyout((caddr_t)&loff, (caddr_t)uap->basep, sizeof(long));
1998 	*retval = uap->count - auio.uio_resid;
1999 	return (error);
2000 }
2001 
2002 /*
2003  * Set the mode mask for creation of filesystem nodes.
2004  */
2005 struct umask_args {
2006 	int	mask;
2007 };
2008 mode_t				/* XXX */
2009 umask(p, uap, retval)
2010 	struct proc *p;
2011 	struct umask_args *uap;
2012 	int *retval;
2013 {
2014 	register struct filedesc *fdp = p->p_fd;
2015 
2016 	*retval = fdp->fd_cmask;
2017 	fdp->fd_cmask = uap->mask & 07777;
2018 	return (0);
2019 }
2020 
2021 /*
2022  * Void all references to file by ripping underlying filesystem
2023  * away from vnode.
2024  */
2025 struct revoke_args {
2026 	char	*fname;
2027 };
2028 /* ARGSUSED */
2029 revoke(p, uap, retval)
2030 	struct proc *p;
2031 	register struct revoke_args *uap;
2032 	int *retval;
2033 {
2034 	register struct vnode *vp;
2035 	struct vattr vattr;
2036 	int error;
2037 	struct nameidata nd;
2038 
2039 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname, p);
2040 	if (error = namei(&nd))
2041 		return (error);
2042 	vp = nd.ni_vp;
2043 	if (vp->v_type != VCHR && vp->v_type != VBLK) {
2044 		error = EINVAL;
2045 		goto out;
2046 	}
2047 	if (error = VOP_GETATTR(vp, &vattr, p->p_ucred, p))
2048 		goto out;
2049 	if (p->p_ucred->cr_uid != vattr.va_uid &&
2050 	    (error = suser(p->p_ucred, &p->p_acflag)))
2051 		goto out;
2052 	if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
2053 		vgoneall(vp);
2054 out:
2055 	vrele(vp);
2056 	return (error);
2057 }
2058 
2059 /*
2060  * Convert a user file descriptor to a kernel file entry.
2061  */
2062 getvnode(fdp, fdes, fpp)
2063 	struct filedesc *fdp;
2064 	struct file **fpp;
2065 	int fdes;
2066 {
2067 	struct file *fp;
2068 
2069 	if ((unsigned)fdes >= fdp->fd_nfiles ||
2070 	    (fp = fdp->fd_ofiles[fdes]) == NULL)
2071 		return (EBADF);
2072 	if (fp->f_type != DTYPE_VNODE)
2073 		return (EINVAL);
2074 	*fpp = fp;
2075 	return (0);
2076 }
2077