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