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