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