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