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