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