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