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