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