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