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