xref: /csrg-svn/sys/kern/vfs_syscalls.c (revision 52230)
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.76 (Berkeley) 01/22/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 		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 	register struct vnode *vp;
560 	int fmode, cmode;
561 	struct file *nfp;
562 	int type, indx, error;
563 	struct flock lf;
564 	struct nameidata nd;
565 	extern struct fileops vnops;
566 
567 	if (error = falloc(p, &nfp, &indx))
568 		return (error);
569 	fp = nfp;
570 	fmode = FFLAGS(uap->mode);
571 	cmode = ((uap->crtmode &~ fdp->fd_cmask) & 07777) &~ S_ISVTX;
572 	ndp = &nd;
573 	ndp->ni_segflg = UIO_USERSPACE;
574 	ndp->ni_dirp = uap->fname;
575 	p->p_dupfd = -indx - 1;			/* XXX check for fdopen */
576 	if (error = vn_open(ndp, p, fmode, cmode)) {
577 		ffree(fp);
578 		if (error == ENODEV &&		/* XXX from fdopen */
579 		    p->p_dupfd >= 0 &&
580 		    (error = dupfdopen(fdp, indx, p->p_dupfd, fmode)) == 0) {
581 			*retval = indx;
582 			return (0);
583 		}
584 		if (error == ERESTART)
585 			error = EINTR;
586 		fdp->fd_ofiles[indx] = NULL;
587 		return (error);
588 	}
589 	vp = ndp->ni_vp;
590 	fp->f_flag = fmode & FMASK;
591 	if (fmode & (O_EXLOCK | O_SHLOCK)) {
592 		lf.l_whence = SEEK_SET;
593 		lf.l_start = 0;
594 		lf.l_len = 0;
595 		if (fmode & O_EXLOCK)
596 			lf.l_type = F_WRLCK;
597 		else
598 			lf.l_type = F_RDLCK;
599 		type = F_FLOCK;
600 		if ((fmode & FNONBLOCK) == 0)
601 			type |= F_WAIT;
602 		if (error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type)) {
603 			VOP_UNLOCK(vp);
604 			(void) vn_close(vp, fp->f_flag, fp->f_cred, p);
605 			ffree(fp);
606 			fdp->fd_ofiles[indx] = NULL;
607 			return (error);
608 		}
609 		fp->f_flag |= FHASLOCK;
610 	}
611 	VOP_UNLOCK(vp);
612 	fp->f_type = DTYPE_VNODE;
613 	fp->f_ops = &vnops;
614 	fp->f_data = (caddr_t)vp;
615 	*retval = indx;
616 	return (0);
617 }
618 
619 #ifdef COMPAT_43
620 /*
621  * Creat system call.
622  */
623 ocreat(p, uap, retval)
624 	struct proc *p;
625 	register struct args {
626 		char	*fname;
627 		int	fmode;
628 	} *uap;
629 	int *retval;
630 {
631 	struct args {
632 		char	*fname;
633 		int	mode;
634 		int	crtmode;
635 	} openuap;
636 
637 	openuap.fname = uap->fname;
638 	openuap.crtmode = uap->fmode;
639 	openuap.mode = O_WRONLY | O_CREAT | O_TRUNC;
640 	return (open(p, &openuap, retval));
641 }
642 #endif /* COMPAT_43 */
643 
644 /*
645  * Mknod system call.
646  */
647 /* ARGSUSED */
648 mknod(p, uap, retval)
649 	struct proc *p;
650 	register struct args {
651 		char	*fname;
652 		int	fmode;
653 		int	dev;
654 	} *uap;
655 	int *retval;
656 {
657 	register struct nameidata *ndp;
658 	register struct vnode *vp;
659 	struct vattr vattr;
660 	int error;
661 	struct nameidata nd;
662 
663 	CHECKPOINT;
664 	if (error = suser(p->p_ucred, &p->p_acflag))
665 		return (error);
666 	ndp = &nd;
667 	ndp->ni_nameiop = CREATE | LOCKPARENT;
668 	ndp->ni_segflg = UIO_USERSPACE;
669 	ndp->ni_dirp = uap->fname;
670 	if (error = namei(ndp, p))
671 		return (error);
672 	vp = ndp->ni_vp;
673 	if (vp != NULL) {
674 		error = EEXIST;
675 		goto out;
676 	}
677 	VATTR_NULL(&vattr);
678 	switch (uap->fmode & S_IFMT) {
679 
680 	case S_IFMT:	/* used by badsect to flag bad sectors */
681 		vattr.va_type = VBAD;
682 		break;
683 	case S_IFCHR:
684 		vattr.va_type = VCHR;
685 		break;
686 	case S_IFBLK:
687 		vattr.va_type = VBLK;
688 		break;
689 	default:
690 		error = EINVAL;
691 		goto out;
692 	}
693 	vattr.va_mode = (uap->fmode & 07777) &~ p->p_fd->fd_cmask;
694 	vattr.va_rdev = uap->dev;
695 out:
696 	if (!error) {
697 		LEASE_CHECK(ndp->ni_dvp, p, p->p_ucred, LEASE_WRITE);
698 		error = VOP_MKNOD(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &vattr);
699 	} else {
700 		VOP_ABORTOP(ndp->ni_dvp, &ndp->ni_cnd);
701 		if (ndp->ni_dvp == vp)
702 			vrele(ndp->ni_dvp);
703 		else
704 			vput(ndp->ni_dvp);
705 		if (vp)
706 			vrele(vp);
707 	}
708 	CHECKCHECK("mknod");
709 	return (error);
710 }
711 
712 /*
713  * Mkfifo system call.
714  */
715 /* ARGSUSED */
716 mkfifo(p, uap, retval)
717 	struct proc *p;
718 	register struct args {
719 		char	*fname;
720 		int	fmode;
721 	} *uap;
722 	int *retval;
723 {
724 	register struct nameidata *ndp;
725 	struct vattr vattr;
726 	int error;
727 	struct nameidata nd;
728 
729 #ifndef FIFO
730 	return (EOPNOTSUPP);
731 #else
732 	ndp = &nd;
733 	ndp->ni_nameiop = CREATE | LOCKPARENT;
734 	ndp->ni_segflg = UIO_USERSPACE;
735 	ndp->ni_dirp = uap->fname;
736 	if (error = namei(ndp, p))
737 		return (error);
738 	if (ndp->ni_vp != NULL) {
739 		VOP_ABORTOP(ndp->ni_dvp, &ndp->ni_cnd);
740 		if (ndp->ni_dvp == ndp->ni_vp)
741 			vrele(ndp->ni_dvp);
742 		else
743 			vput(ndp->ni_dvp);
744 		vrele(ndp->ni_vp);
745 		return (EEXIST);
746 	}
747 	VATTR_NULL(&vattr);
748 	vattr.va_type = VFIFO;
749 	vattr.va_mode = (uap->fmode & 07777) &~ p->p_fd->fd_cmask;
750 	LEASE_CHECK(ndp->ni_dvp, p, p->p_ucred, LEASE_WRITE);
751 	return (VOP_MKNOD(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &vattr));
752 #endif /* FIFO */
753 }
754 
755 /*
756  * Link system call.
757  */
758 /* ARGSUSED */
759 link(p, uap, retval)
760 	struct proc *p;
761 	register struct args {
762 		char	*target;
763 		char	*linkname;
764 	} *uap;
765 	int *retval;
766 {
767 	register struct nameidata *ndp;
768 	register struct vnode *vp, *xp;
769 	int error;
770 	struct nameidata nd;
771 
772 	CHECKPOINT;
773 	ndp = &nd;
774 	ndp->ni_nameiop = LOOKUP | FOLLOW;
775 	ndp->ni_segflg = UIO_USERSPACE;
776 	ndp->ni_dirp = uap->target;
777 	if (error = namei(ndp, p))
778 		return (error);
779 	vp = ndp->ni_vp;
780 	if (vp->v_type == VDIR &&
781 	    (error = suser(p->p_ucred, &p->p_acflag)))
782 		goto out1;
783 	ndp->ni_nameiop = CREATE | LOCKPARENT;
784 	ndp->ni_dirp = (caddr_t)uap->linkname;
785 	if (error = namei(ndp, p))
786 		goto out1;
787 	xp = ndp->ni_vp;
788 	if (xp != NULL) {
789 		error = EEXIST;
790 		goto out;
791 	}
792 	xp = ndp->ni_dvp;
793 	if (vp->v_mount != xp->v_mount)
794 		error = EXDEV;
795 out:
796 	if (!error) {
797 		LEASE_CHECK(xp, p, p->p_ucred, LEASE_WRITE);
798 		LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
799 		error = VOP_LINK(vp, ndp->ni_dvp, &ndp->ni_cnd);
800 	} else {
801 		VOP_ABORTOP(ndp->ni_dvp, &ndp->ni_cnd);
802 		if (ndp->ni_dvp == ndp->ni_vp)
803 			vrele(ndp->ni_dvp);
804 		else
805 			vput(ndp->ni_dvp);
806 		if (ndp->ni_vp)
807 			vrele(ndp->ni_vp);
808 	}
809 out1:
810 	vrele(vp);
811 	CHECKCHECK("link");
812 	return (error);
813 }
814 
815 /*
816  * Make a symbolic link.
817  */
818 /* ARGSUSED */
819 symlink(p, uap, retval)
820 	struct proc *p;
821 	register struct args {
822 		char	*target;
823 		char	*linkname;
824 	} *uap;
825 	int *retval;
826 {
827 	register struct nameidata *ndp;
828 	struct vattr vattr;
829 	char *target;
830 	int error;
831 	struct nameidata nd;
832 
833 	CHECKPOINT;
834 	ndp = &nd;
835 	ndp->ni_segflg = UIO_USERSPACE;
836 	ndp->ni_dirp = uap->linkname;
837 	MALLOC(target, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
838 	if (error = copyinstr(uap->target, target, MAXPATHLEN, (u_int *)0))
839 		goto out;
840 	ndp->ni_nameiop = CREATE | LOCKPARENT;
841 	if (error = namei(ndp, p))
842 		goto out;
843 	if (ndp->ni_vp) {
844 		VOP_ABORTOP(ndp->ni_dvp, &ndp->ni_cnd);
845 		if (ndp->ni_dvp == ndp->ni_vp)
846 			vrele(ndp->ni_dvp);
847 		else
848 			vput(ndp->ni_dvp);
849 		vrele(ndp->ni_vp);
850 		error = EEXIST;
851 		goto out;
852 	}
853 	VATTR_NULL(&vattr);
854 	vattr.va_mode = 0777 &~ p->p_fd->fd_cmask;
855 	LEASE_CHECK(ndp->ni_dvp, p, p->p_ucred, LEASE_WRITE);
856 	error = VOP_SYMLINK(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &vattr, target);
857 out:
858 	FREE(target, M_NAMEI);
859 	CHECKCHECK("symlink");
860 	return (error);
861 }
862 
863 /*
864  * Delete a name from the filesystem.
865  */
866 /* ARGSUSED */
867 unlink(p, uap, retval)
868 	struct proc *p;
869 	struct args {
870 		char	*fname;
871 	} *uap;
872 	int *retval;
873 {
874 	register struct nameidata *ndp;
875 	register struct vnode *vp;
876 	int error;
877 	struct nameidata nd;
878 
879 	CHECKPOINT;
880 	ndp = &nd;
881 	ndp->ni_nameiop = DELETE | LOCKPARENT | LOCKLEAF;
882 	ndp->ni_segflg = UIO_USERSPACE;
883 	ndp->ni_dirp = uap->fname;
884 	if (error = namei(ndp, p))
885 		return (error);
886 	vp = ndp->ni_vp;
887 	if (vp->v_type == VDIR &&
888 	    (error = suser(p->p_ucred, &p->p_acflag)))
889 		goto out;
890 	/*
891 	 * The root of a mounted filesystem cannot be deleted.
892 	 */
893 	if (vp->v_flag & VROOT) {
894 		error = EBUSY;
895 		goto out;
896 	}
897 	(void) vnode_pager_uncache(vp);
898 out:
899 	if (!error) {
900 		LEASE_CHECK(ndp->ni_dvp, p, p->p_ucred, LEASE_WRITE);
901 		LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
902 		error = VOP_REMOVE(ndp->ni_dvp, ndp->ni_vp, &ndp->ni_cnd);
903 	} else {
904 		VOP_ABORTOP(ndp->ni_dvp, &ndp->ni_cnd);
905 		if (ndp->ni_dvp == vp)
906 			vrele(ndp->ni_dvp);
907 		else
908 			vput(ndp->ni_dvp);
909 		vput(vp);
910 	}
911 	CHECKCHECK("unlink");
912 	return (error);
913 }
914 
915 /*
916  * Seek system call.
917  */
918 lseek(p, uap, retval)
919 	struct proc *p;
920 	register struct args {
921 		int	fdes;
922 		off_t	off;
923 		int	sbase;
924 	} *uap;
925 	off_t *retval;
926 {
927 	struct ucred *cred = p->p_ucred;
928 	register struct filedesc *fdp = p->p_fd;
929 	register struct file *fp;
930 	struct vattr vattr;
931 	int error;
932 
933 	if ((unsigned)uap->fdes >= fdp->fd_nfiles ||
934 	    (fp = fdp->fd_ofiles[uap->fdes]) == NULL)
935 		return (EBADF);
936 	if (fp->f_type != DTYPE_VNODE)
937 		return (ESPIPE);
938 	switch (uap->sbase) {
939 
940 	case L_INCR:
941 		fp->f_offset += uap->off;
942 		break;
943 
944 	case L_XTND:
945 		if (error = VOP_GETATTR((struct vnode *)fp->f_data,
946 		    &vattr, cred, p))
947 			return (error);
948 		fp->f_offset = uap->off + vattr.va_size;
949 		break;
950 
951 	case L_SET:
952 		fp->f_offset = uap->off;
953 		break;
954 
955 	default:
956 		return (EINVAL);
957 	}
958 	*retval = fp->f_offset;
959 	return (0);
960 }
961 
962 /*
963  * Check access permissions.
964  */
965 /* ARGSUSED */
966 saccess(p, uap, retval)
967 	struct proc *p;
968 	register struct args {
969 		char	*fname;
970 		int	fmode;
971 	} *uap;
972 	int *retval;
973 {
974 	register struct nameidata *ndp;
975 	register struct ucred *cred = p->p_ucred;
976 	register struct vnode *vp;
977 	int error, mode, svuid, svgid;
978 	struct nameidata nd;
979 
980 	ndp = &nd;
981 	svuid = cred->cr_uid;
982 	svgid = cred->cr_groups[0];
983 	cred->cr_uid = p->p_cred->p_ruid;
984 	cred->cr_groups[0] = p->p_cred->p_rgid;
985 	ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
986 	ndp->ni_segflg = UIO_USERSPACE;
987 	ndp->ni_dirp = uap->fname;
988 	if (error = namei(ndp, p))
989 		goto out1;
990 	vp = ndp->ni_vp;
991 	/*
992 	 * fmode == 0 means only check for exist
993 	 */
994 	if (uap->fmode) {
995 		mode = 0;
996 		if (uap->fmode & R_OK)
997 			mode |= VREAD;
998 		if (uap->fmode & W_OK)
999 			mode |= VWRITE;
1000 		if (uap->fmode & X_OK)
1001 			mode |= VEXEC;
1002 		if ((mode & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)
1003 			error = VOP_ACCESS(vp, mode, cred, p);
1004 	}
1005 	vput(vp);
1006 out1:
1007 	cred->cr_uid = svuid;
1008 	cred->cr_groups[0] = svgid;
1009 	return (error);
1010 }
1011 
1012 /*
1013  * Stat system call.
1014  * This version follows links.
1015  */
1016 /* ARGSUSED */
1017 stat(p, uap, retval)
1018 	struct proc *p;
1019 	register struct args {
1020 		char	*fname;
1021 		struct stat *ub;
1022 	} *uap;
1023 	int *retval;
1024 {
1025 	register struct nameidata *ndp;
1026 	struct stat sb;
1027 	int error;
1028 	struct nameidata nd;
1029 
1030 	ndp = &nd;
1031 	ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW;
1032 	ndp->ni_segflg = UIO_USERSPACE;
1033 	ndp->ni_dirp = uap->fname;
1034 	if (error = namei(ndp, p))
1035 		return (error);
1036 	error = vn_stat(ndp->ni_vp, &sb, p);
1037 	vput(ndp->ni_vp);
1038 	if (error)
1039 		return (error);
1040 	error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
1041 	return (error);
1042 }
1043 
1044 /*
1045  * Lstat system call.
1046  * This version does not follow links.
1047  */
1048 /* ARGSUSED */
1049 lstat(p, uap, retval)
1050 	struct proc *p;
1051 	register struct args {
1052 		char	*fname;
1053 		struct stat *ub;
1054 	} *uap;
1055 	int *retval;
1056 {
1057 	register struct nameidata *ndp;
1058 	struct stat sb;
1059 	int error;
1060 	struct nameidata nd;
1061 
1062 	ndp = &nd;
1063 	ndp->ni_nameiop = LOOKUP | LOCKLEAF | NOFOLLOW;
1064 	ndp->ni_segflg = UIO_USERSPACE;
1065 	ndp->ni_dirp = uap->fname;
1066 	if (error = namei(ndp, p))
1067 		return (error);
1068 	error = vn_stat(ndp->ni_vp, &sb, p);
1069 	vput(ndp->ni_vp);
1070 	if (error)
1071 		return (error);
1072 	error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
1073 	return (error);
1074 }
1075 
1076 /*
1077  * Return target name of a symbolic link.
1078  */
1079 /* ARGSUSED */
1080 readlink(p, uap, retval)
1081 	struct proc *p;
1082 	register struct args {
1083 		char	*name;
1084 		char	*buf;
1085 		int	count;
1086 	} *uap;
1087 	int *retval;
1088 {
1089 	register struct nameidata *ndp;
1090 	register struct vnode *vp;
1091 	struct iovec aiov;
1092 	struct uio auio;
1093 	int error;
1094 	struct nameidata nd;
1095 
1096 	CHECKPOINT;
1097 	ndp = &nd;
1098 	ndp->ni_nameiop = LOOKUP | LOCKLEAF;
1099 	ndp->ni_segflg = UIO_USERSPACE;
1100 	ndp->ni_dirp = uap->name;
1101 	if (error = namei(ndp, p))
1102 		return (error);
1103 	vp = ndp->ni_vp;
1104 	if (vp->v_type != VLNK) {
1105 		error = EINVAL;
1106 		goto out;
1107 	}
1108 	aiov.iov_base = uap->buf;
1109 	aiov.iov_len = uap->count;
1110 	auio.uio_iov = &aiov;
1111 	auio.uio_iovcnt = 1;
1112 	auio.uio_offset = 0;
1113 	auio.uio_rw = UIO_READ;
1114 	auio.uio_segflg = UIO_USERSPACE;
1115 	auio.uio_procp = p;
1116 	auio.uio_resid = uap->count;
1117 	error = VOP_READLINK(vp, &auio, p->p_ucred);
1118 out:
1119 	vput(vp);
1120 	*retval = uap->count - auio.uio_resid;
1121 	CHECKCHECK("readlink");
1122 	return (error);
1123 }
1124 
1125 /*
1126  * Change flags of a file given path name.
1127  */
1128 /* ARGSUSED */
1129 chflags(p, uap, retval)
1130 	struct proc *p;
1131 	register struct args {
1132 		char	*fname;
1133 		int	flags;
1134 	} *uap;
1135 	int *retval;
1136 {
1137 	register struct nameidata *ndp;
1138 	register struct vnode *vp;
1139 	struct vattr vattr;
1140 	int error;
1141 	struct nameidata nd;
1142 
1143 	ndp = &nd;
1144 	ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
1145 	ndp->ni_segflg = UIO_USERSPACE;
1146 	ndp->ni_dirp = uap->fname;
1147 	if (error = namei(ndp, p))
1148 		return (error);
1149 	vp = ndp->ni_vp;
1150 	if (vp->v_mount->mnt_flag & MNT_RDONLY) {
1151 		error = EROFS;
1152 		goto out;
1153 	}
1154 	VATTR_NULL(&vattr);
1155 	vattr.va_flags = uap->flags;
1156 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1157 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1158 out:
1159 	vput(vp);
1160 	return (error);
1161 }
1162 
1163 /*
1164  * Change flags of a file given a file descriptor.
1165  */
1166 /* ARGSUSED */
1167 fchflags(p, uap, retval)
1168 	struct proc *p;
1169 	register struct args {
1170 		int	fd;
1171 		int	flags;
1172 	} *uap;
1173 	int *retval;
1174 {
1175 	struct vattr vattr;
1176 	struct vnode *vp;
1177 	struct file *fp;
1178 	int error;
1179 
1180 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1181 		return (error);
1182 	vp = (struct vnode *)fp->f_data;
1183 	VOP_LOCK(vp);
1184 	if (vp->v_mount->mnt_flag & MNT_RDONLY) {
1185 		error = EROFS;
1186 		goto out;
1187 	}
1188 	VATTR_NULL(&vattr);
1189 	vattr.va_flags = uap->flags;
1190 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1191 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1192 out:
1193 	VOP_UNLOCK(vp);
1194 	return (error);
1195 }
1196 
1197 /*
1198  * Change mode of a file given path name.
1199  */
1200 /* ARGSUSED */
1201 chmod(p, uap, retval)
1202 	struct proc *p;
1203 	register struct args {
1204 		char	*fname;
1205 		int	fmode;
1206 	} *uap;
1207 	int *retval;
1208 {
1209 	register struct nameidata *ndp;
1210 	register struct vnode *vp;
1211 	struct vattr vattr;
1212 	int error;
1213 	struct nameidata nd;
1214 
1215 	ndp = &nd;
1216 	ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
1217 	ndp->ni_segflg = UIO_USERSPACE;
1218 	ndp->ni_dirp = uap->fname;
1219 	if (error = namei(ndp, p))
1220 		return (error);
1221 	vp = ndp->ni_vp;
1222 	if (vp->v_mount->mnt_flag & MNT_RDONLY) {
1223 		error = EROFS;
1224 		goto out;
1225 	}
1226 	VATTR_NULL(&vattr);
1227 	vattr.va_mode = uap->fmode & 07777;
1228 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1229 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1230 out:
1231 	vput(vp);
1232 	return (error);
1233 }
1234 
1235 /*
1236  * Change mode of a file given a file descriptor.
1237  */
1238 /* ARGSUSED */
1239 fchmod(p, uap, retval)
1240 	struct proc *p;
1241 	register struct args {
1242 		int	fd;
1243 		int	fmode;
1244 	} *uap;
1245 	int *retval;
1246 {
1247 	struct vattr vattr;
1248 	struct vnode *vp;
1249 	struct file *fp;
1250 	int error;
1251 
1252 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1253 		return (error);
1254 	vp = (struct vnode *)fp->f_data;
1255 	VOP_LOCK(vp);
1256 	if (vp->v_mount->mnt_flag & MNT_RDONLY) {
1257 		error = EROFS;
1258 		goto out;
1259 	}
1260 	VATTR_NULL(&vattr);
1261 	vattr.va_mode = uap->fmode & 07777;
1262 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1263 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1264 out:
1265 	VOP_UNLOCK(vp);
1266 	return (error);
1267 }
1268 
1269 /*
1270  * Set ownership given a path name.
1271  */
1272 /* ARGSUSED */
1273 chown(p, uap, retval)
1274 	struct proc *p;
1275 	register struct args {
1276 		char	*fname;
1277 		int	uid;
1278 		int	gid;
1279 	} *uap;
1280 	int *retval;
1281 {
1282 	register struct nameidata *ndp;
1283 	register struct vnode *vp;
1284 	struct vattr vattr;
1285 	int error;
1286 	struct nameidata nd;
1287 
1288 	ndp = &nd;
1289 	ndp->ni_nameiop = LOOKUP | NOFOLLOW | LOCKLEAF;
1290 	ndp->ni_segflg = UIO_USERSPACE;
1291 	ndp->ni_dirp = uap->fname;
1292 	if (error = namei(ndp, p))
1293 		return (error);
1294 	vp = ndp->ni_vp;
1295 	if (vp->v_mount->mnt_flag & MNT_RDONLY) {
1296 		error = EROFS;
1297 		goto out;
1298 	}
1299 	VATTR_NULL(&vattr);
1300 	vattr.va_uid = uap->uid;
1301 	vattr.va_gid = uap->gid;
1302 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1303 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1304 out:
1305 	vput(vp);
1306 	return (error);
1307 }
1308 
1309 /*
1310  * Set ownership given a file descriptor.
1311  */
1312 /* ARGSUSED */
1313 fchown(p, uap, retval)
1314 	struct proc *p;
1315 	register struct args {
1316 		int	fd;
1317 		int	uid;
1318 		int	gid;
1319 	} *uap;
1320 	int *retval;
1321 {
1322 	struct vattr vattr;
1323 	struct vnode *vp;
1324 	struct file *fp;
1325 	int error;
1326 
1327 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1328 		return (error);
1329 	vp = (struct vnode *)fp->f_data;
1330 	VOP_LOCK(vp);
1331 	if (vp->v_mount->mnt_flag & MNT_RDONLY) {
1332 		error = EROFS;
1333 		goto out;
1334 	}
1335 	VATTR_NULL(&vattr);
1336 	vattr.va_uid = uap->uid;
1337 	vattr.va_gid = uap->gid;
1338 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1339 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1340 out:
1341 	VOP_UNLOCK(vp);
1342 	return (error);
1343 }
1344 
1345 /*
1346  * Set the access and modification times of a file.
1347  */
1348 /* ARGSUSED */
1349 utimes(p, uap, retval)
1350 	struct proc *p;
1351 	register struct args {
1352 		char	*fname;
1353 		struct	timeval *tptr;
1354 	} *uap;
1355 	int *retval;
1356 {
1357 	register struct nameidata *ndp;
1358 	register struct vnode *vp;
1359 	struct timeval tv[2];
1360 	struct vattr vattr;
1361 	int error;
1362 	struct nameidata nd;
1363 
1364 	if (error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv)))
1365 		return (error);
1366 	ndp = &nd;
1367 	ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
1368 	ndp->ni_segflg = UIO_USERSPACE;
1369 	ndp->ni_dirp = uap->fname;
1370 	if (error = namei(ndp, p))
1371 		return (error);
1372 	vp = ndp->ni_vp;
1373 	if (vp->v_mount->mnt_flag & MNT_RDONLY) {
1374 		error = EROFS;
1375 		goto out;
1376 	}
1377 	VATTR_NULL(&vattr);
1378 	vattr.va_atime = tv[0];
1379 	vattr.va_mtime = tv[1];
1380 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1381 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1382 out:
1383 	vput(vp);
1384 	return (error);
1385 }
1386 
1387 /*
1388  * Truncate a file given its path name.
1389  */
1390 /* ARGSUSED */
1391 truncate(p, uap, retval)
1392 	struct proc *p;
1393 	register struct args {
1394 		char	*fname;
1395 		off_t	length;
1396 	} *uap;
1397 	int *retval;
1398 {
1399 	register struct nameidata *ndp;
1400 	register struct vnode *vp;
1401 	struct vattr vattr;
1402 	int error;
1403 	struct nameidata nd;
1404 
1405 	ndp = &nd;
1406 	ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF;
1407 	ndp->ni_segflg = UIO_USERSPACE;
1408 	ndp->ni_dirp = uap->fname;
1409 	if (error = namei(ndp, p))
1410 		return (error);
1411 	vp = ndp->ni_vp;
1412 	if (vp->v_type == VDIR) {
1413 		error = EISDIR;
1414 		goto out;
1415 	}
1416 	if ((error = vn_writechk(vp)) ||
1417 	    (error = VOP_ACCESS(vp, VWRITE, p->p_ucred, p)))
1418 		goto out;
1419 	VATTR_NULL(&vattr);
1420 	vattr.va_size = uap->length;
1421 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1422 	error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
1423 out:
1424 	vput(vp);
1425 	return (error);
1426 }
1427 
1428 /*
1429  * Truncate a file given a file descriptor.
1430  */
1431 /* ARGSUSED */
1432 ftruncate(p, uap, retval)
1433 	struct proc *p;
1434 	register struct args {
1435 		int	fd;
1436 		off_t	length;
1437 	} *uap;
1438 	int *retval;
1439 {
1440 	struct vattr vattr;
1441 	struct vnode *vp;
1442 	struct file *fp;
1443 	int error;
1444 
1445 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1446 		return (error);
1447 	if ((fp->f_flag & FWRITE) == 0)
1448 		return (EINVAL);
1449 	vp = (struct vnode *)fp->f_data;
1450 	VOP_LOCK(vp);
1451 	if (vp->v_type == VDIR) {
1452 		error = EISDIR;
1453 		goto out;
1454 	}
1455 	if (error = vn_writechk(vp))
1456 		goto out;
1457 	VATTR_NULL(&vattr);
1458 	vattr.va_size = uap->length;
1459 	LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1460 	error = VOP_SETATTR(vp, &vattr, fp->f_cred, p);
1461 out:
1462 	VOP_UNLOCK(vp);
1463 	return (error);
1464 }
1465 
1466 /*
1467  * Synch an open file.
1468  */
1469 /* ARGSUSED */
1470 fsync(p, uap, retval)
1471 	struct proc *p;
1472 	struct args {
1473 		int	fd;
1474 	} *uap;
1475 	int *retval;
1476 {
1477 	register struct vnode *vp;
1478 	struct file *fp;
1479 	int error;
1480 
1481 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1482 		return (error);
1483 	vp = (struct vnode *)fp->f_data;
1484 	VOP_LOCK(vp);
1485 	error = VOP_FSYNC(vp, fp->f_flag, fp->f_cred, MNT_WAIT, p);
1486 	VOP_UNLOCK(vp);
1487 	return (error);
1488 }
1489 
1490 /*
1491  * Rename system call.
1492  *
1493  * Source and destination must either both be directories, or both
1494  * not be directories.  If target is a directory, it must be empty.
1495  */
1496 /* ARGSUSED */
1497 rename(p, uap, retval)
1498 	struct proc *p;
1499 	register struct args {
1500 		char	*from;
1501 		char	*to;
1502 	} *uap;
1503 	int *retval;
1504 {
1505 	register struct vnode *tvp, *fvp, *tdvp;
1506 	struct nameidata fromnd, tond;
1507 	int error;
1508 
1509 	CHECKPOINT;
1510 	fromnd.ni_nameiop = DELETE | WANTPARENT | SAVESTART;
1511 	fromnd.ni_segflg = UIO_USERSPACE;
1512 	fromnd.ni_dirp = uap->from;
1513 	if (error = namei(&fromnd, p))
1514 		return (error);
1515 	fvp = fromnd.ni_vp;
1516 	tond.ni_nameiop = RENAME | LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART;
1517 	tond.ni_segflg = UIO_USERSPACE;
1518 	tond.ni_dirp = uap->to;
1519 	if (error = namei(&tond, p)) {
1520 		VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
1521 		vrele(fromnd.ni_dvp);
1522 		vrele(fvp);
1523 		goto out1;
1524 	}
1525 	tdvp = tond.ni_dvp;
1526 	tvp = tond.ni_vp;
1527 	if (tvp != NULL) {
1528 		if (fvp->v_type == VDIR && tvp->v_type != VDIR) {
1529 			error = ENOTDIR;
1530 			goto out;
1531 		} else if (fvp->v_type != VDIR && tvp->v_type == VDIR) {
1532 			error = EISDIR;
1533 			goto out;
1534 		}
1535 		if (fvp->v_mount != tvp->v_mount) {
1536 			error = EXDEV;
1537 			goto out;
1538 		}
1539 	}
1540 	if (fvp->v_mount != tdvp->v_mount) {
1541 		error = EXDEV;
1542 		goto out;
1543 	}
1544 	if (fvp == tdvp)
1545 		error = EINVAL;
1546 	/*
1547 	 * If source is the same as the destination (that is the
1548 	 * same inode number with the same name in the same directory),
1549 	 * then there is nothing to do.
1550 	 */
1551 	if (fvp == tvp && fromnd.ni_dvp == tdvp &&
1552 	    fromnd.ni_namelen == tond.ni_namelen &&
1553 	    !bcmp(fromnd.ni_ptr, tond.ni_ptr, fromnd.ni_namelen))
1554 		error = -1;
1555 out:
1556 	if (!error) {
1557 		LEASE_CHECK(tdvp, p, p->p_ucred, LEASE_WRITE);
1558 		if (fromnd.ni_dvp != tdvp)
1559 			LEASE_CHECK(fromnd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
1560 		if (tvp)
1561 			LEASE_CHECK(tvp, p, p->p_ucred, LEASE_WRITE);
1562 		if (fromnd.ni_startdir != fromnd.ni_dvp ||
1563 		    tond.ni_startdir != tond.ni_dvp)   /* NEEDSWORK: debug */
1564 			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);
1565 		error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd,
1566 				   tond.ni_dvp, tond.ni_vp, &tond.ni_cnd);
1567 		if (fromnd.ni_startdir != fromnd.ni_dvp ||
1568 		    tond.ni_startdir != tond.ni_dvp)   /* NEEDSWORK: debug */
1569 			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);
1570 	} else {
1571 		VOP_ABORTOP(tond.ni_dvp, &tond.ni_cnd);
1572 		if (tdvp == tvp)
1573 			vrele(tdvp);
1574 		else
1575 			vput(tdvp);
1576 		if (tvp)
1577 			vput(tvp);
1578 		VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
1579 		vrele(fromnd.ni_dvp);
1580 		vrele(fvp);
1581 	}
1582 	vrele(tond.ni_startdir);
1583 	FREE(tond.ni_pnbuf, M_NAMEI);
1584 out1:
1585 	vrele(fromnd.ni_startdir);
1586 	FREE(fromnd.ni_pnbuf, M_NAMEI);
1587 	CHECKCHECK("rename");
1588 	if (error == -1)
1589 		return (0);
1590 	return (error);
1591 }
1592 
1593 /*
1594  * Mkdir system call.
1595  */
1596 /* ARGSUSED */
1597 mkdir(p, uap, retval)
1598 	struct proc *p;
1599 	register struct args {
1600 		char	*name;
1601 		int	dmode;
1602 	} *uap;
1603 	int *retval;
1604 {
1605 	register struct nameidata *ndp;
1606 	register struct vnode *vp;
1607 	struct vattr vattr;
1608 	int error;
1609 	struct nameidata nd;
1610 
1611 	CHECKPOINT;
1612 	ndp = &nd;
1613 	ndp->ni_nameiop = CREATE | LOCKPARENT;
1614 	ndp->ni_segflg = UIO_USERSPACE;
1615 	ndp->ni_dirp = uap->name;
1616 	if (error = namei(ndp, p))
1617 		return (error);
1618 	vp = ndp->ni_vp;
1619 	if (vp != NULL) {
1620 		VOP_ABORTOP(ndp->ni_dvp, &ndp->ni_cnd);
1621 		if (ndp->ni_dvp == vp)
1622 			vrele(ndp->ni_dvp);
1623 		else
1624 			vput(ndp->ni_dvp);
1625 		vrele(vp);
1626 		CHECKCHECK("mkdir1");
1627 		return (EEXIST);
1628 	}
1629 	VATTR_NULL(&vattr);
1630 	vattr.va_type = VDIR;
1631 	vattr.va_mode = (uap->dmode & 0777) &~ p->p_fd->fd_cmask;
1632 	LEASE_CHECK(ndp->ni_dvp, p, p->p_ucred, LEASE_WRITE);
1633 	error = VOP_MKDIR(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, &vattr);
1634 	if (!error)
1635 		vput(ndp->ni_vp);
1636 	CHECKCHECK("mkdir2");
1637 	return (error);
1638 }
1639 
1640 /*
1641  * Rmdir system call.
1642  */
1643 /* ARGSUSED */
1644 rmdir(p, uap, retval)
1645 	struct proc *p;
1646 	struct args {
1647 		char	*name;
1648 	} *uap;
1649 	int *retval;
1650 {
1651 	register struct nameidata *ndp;
1652 	register struct vnode *vp;
1653 	int error;
1654 	struct nameidata nd;
1655 
1656 	CHECKPOINT;
1657 	ndp = &nd;
1658 	ndp->ni_nameiop = DELETE | LOCKPARENT | LOCKLEAF;
1659 	ndp->ni_segflg = UIO_USERSPACE;
1660 	ndp->ni_dirp = uap->name;
1661 	if (error = namei(ndp, p))
1662 		return (error);
1663 	vp = ndp->ni_vp;
1664 	if (vp->v_type != VDIR) {
1665 		error = ENOTDIR;
1666 		goto out;
1667 	}
1668 	/*
1669 	 * No rmdir "." please.
1670 	 */
1671 	if (ndp->ni_dvp == vp) {
1672 		error = EINVAL;
1673 		goto out;
1674 	}
1675 	/*
1676 	 * The root of a mounted filesystem cannot be deleted.
1677 	 */
1678 	if (vp->v_flag & VROOT)
1679 		error = EBUSY;
1680 out:
1681 	if (!error) {
1682 		LEASE_CHECK(ndp->ni_dvp, p, p->p_ucred, LEASE_WRITE);
1683 		LEASE_CHECK(vp, p, p->p_ucred, LEASE_WRITE);
1684 		error = VOP_RMDIR(ndp->ni_dvp, ndp->ni_vp, &ndp->ni_cnd);
1685 	} else {
1686 		VOP_ABORTOP(ndp->ni_dvp, &ndp->ni_cnd);
1687 		if (ndp->ni_dvp == vp)
1688 			vrele(ndp->ni_dvp);
1689 		else
1690 			vput(ndp->ni_dvp);
1691 		vput(vp);
1692 	}
1693 	CHECKCHECK("rmdir");
1694 	return (error);
1695 }
1696 
1697 /*
1698  * Read a block of directory entries in a file system independent format.
1699  */
1700 getdirentries(p, uap, retval)
1701 	struct proc *p;
1702 	register struct args {
1703 		int	fd;
1704 		char	*buf;
1705 		unsigned count;
1706 		long	*basep;
1707 	} *uap;
1708 	int *retval;
1709 {
1710 	register struct vnode *vp;
1711 	struct file *fp;
1712 	struct uio auio;
1713 	struct iovec aiov;
1714 	off_t off;
1715 	int error, eofflag;
1716 
1717 	if (error = getvnode(p->p_fd, uap->fd, &fp))
1718 		return (error);
1719 	if ((fp->f_flag & FREAD) == 0)
1720 		return (EBADF);
1721 	vp = (struct vnode *)fp->f_data;
1722 	if (vp->v_type != VDIR)
1723 		return (EINVAL);
1724 	aiov.iov_base = uap->buf;
1725 	aiov.iov_len = uap->count;
1726 	auio.uio_iov = &aiov;
1727 	auio.uio_iovcnt = 1;
1728 	auio.uio_rw = UIO_READ;
1729 	auio.uio_segflg = UIO_USERSPACE;
1730 	auio.uio_procp = p;
1731 	auio.uio_resid = uap->count;
1732 	VOP_LOCK(vp);
1733 	auio.uio_offset = off = fp->f_offset;
1734 	error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag);
1735 	fp->f_offset = auio.uio_offset;
1736 	VOP_UNLOCK(vp);
1737 	if (error)
1738 		return (error);
1739 	error = copyout((caddr_t)&off, (caddr_t)uap->basep, sizeof(long));
1740 	*retval = uap->count - auio.uio_resid;
1741 	return (error);
1742 }
1743 
1744 /*
1745  * Set the mode mask for creation of filesystem nodes.
1746  */
1747 mode_t
1748 umask(p, uap, retval)
1749 	struct proc *p;
1750 	struct args {
1751 		int	mask;
1752 	} *uap;
1753 	int *retval;
1754 {
1755 	register struct filedesc *fdp = p->p_fd;
1756 
1757 	*retval = fdp->fd_cmask;
1758 	fdp->fd_cmask = uap->mask & 07777;
1759 	return (0);
1760 }
1761 
1762 /*
1763  * Void all references to file by ripping underlying filesystem
1764  * away from vnode.
1765  */
1766 /* ARGSUSED */
1767 revoke(p, uap, retval)
1768 	struct proc *p;
1769 	register struct args {
1770 		char	*fname;
1771 	} *uap;
1772 	int *retval;
1773 {
1774 	register struct nameidata *ndp;
1775 	register struct vnode *vp;
1776 	struct vattr vattr;
1777 	int error;
1778 	struct nameidata nd;
1779 
1780 	ndp = &nd;
1781 	ndp->ni_nameiop = LOOKUP | FOLLOW;
1782 	ndp->ni_segflg = UIO_USERSPACE;
1783 	ndp->ni_dirp = uap->fname;
1784 	if (error = namei(ndp, p))
1785 		return (error);
1786 	vp = ndp->ni_vp;
1787 	if (vp->v_type != VCHR && vp->v_type != VBLK) {
1788 		error = EINVAL;
1789 		goto out;
1790 	}
1791 	if (error = VOP_GETATTR(vp, &vattr, p->p_ucred, p))
1792 		goto out;
1793 	if (p->p_ucred->cr_uid != vattr.va_uid &&
1794 	    (error = suser(p->p_ucred, &p->p_acflag)))
1795 		goto out;
1796 	if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
1797 		vgoneall(vp);
1798 out:
1799 	vrele(vp);
1800 	return (error);
1801 }
1802 
1803 /*
1804  * Convert a user file descriptor to a kernel file entry.
1805  */
1806 getvnode(fdp, fdes, fpp)
1807 	struct filedesc *fdp;
1808 	struct file **fpp;
1809 	int fdes;
1810 {
1811 	struct file *fp;
1812 
1813 	if ((unsigned)fdes >= fdp->fd_nfiles ||
1814 	    (fp = fdp->fd_ofiles[fdes]) == NULL)
1815 		return (EBADF);
1816 	if (fp->f_type != DTYPE_VNODE)
1817 		return (EINVAL);
1818 	*fpp = fp;
1819 	return (0);
1820 }
1821