xref: /original-bsd/sys/ufs/ufs/ufs_vnops.c (revision bb2d502b)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)ufs_vnops.c	7.5 (Berkeley) 02/16/89
7  */
8 
9 #include "param.h"
10 #include "systm.h"
11 #include "dir.h"
12 #include "user.h"
13 #include "kernel.h"
14 #include "file.h"
15 #include "stat.h"
16 #include "inode.h"
17 #include "fs.h"
18 #include "buf.h"
19 #include "proc.h"
20 #include "quota.h"
21 #include "uio.h"
22 #include "socket.h"
23 #include "socketvar.h"
24 #include "mount.h"
25 
26 extern	struct fileops inodeops;
27 struct	file *getinode();
28 
29 /*
30  * Change current working directory (``.'').
31  */
32 chdir()
33 {
34 
35 	chdirec(&u.u_cdir);
36 }
37 
38 /*
39  * Change notion of root (``/'') directory.
40  */
41 chroot()
42 {
43 
44 	if (suser())
45 		chdirec(&u.u_rdir);
46 }
47 
48 /*
49  * Common routine for chroot and chdir.
50  */
51 chdirec(ipp)
52 	register struct inode **ipp;
53 {
54 	register struct inode *ip;
55 	struct a {
56 		char	*fname;
57 	} *uap = (struct a *)u.u_ap;
58 	register struct nameidata *ndp = &u.u_nd;
59 
60 	ndp->ni_nameiop = LOOKUP | FOLLOW;
61 	ndp->ni_segflg = UIO_USERSPACE;
62 	ndp->ni_dirp = uap->fname;
63 	ip = namei(ndp);
64 	if (ip == NULL)
65 		return;
66 	if ((ip->i_mode&IFMT) != IFDIR) {
67 		u.u_error = ENOTDIR;
68 		goto bad;
69 	}
70 	if (access(ip, IEXEC))
71 		goto bad;
72 	IUNLOCK(ip);
73 	if (*ipp)
74 		irele(*ipp);
75 	*ipp = ip;
76 	return;
77 
78 bad:
79 	iput(ip);
80 }
81 
82 /*
83  * Open system call.
84  */
85 open()
86 {
87 	struct a {
88 		char	*fname;
89 		int	mode;
90 		int	crtmode;
91 	} *uap = (struct a *) u.u_ap;
92 
93 	copen(uap->mode-FOPEN, uap->crtmode, uap->fname);
94 }
95 
96 /*
97  * Creat system call.
98  */
99 creat()
100 {
101 	struct a {
102 		char	*fname;
103 		int	fmode;
104 	} *uap = (struct a *)u.u_ap;
105 
106 	copen(FWRITE|FCREAT|FTRUNC, uap->fmode, uap->fname);
107 }
108 
109 /*
110  * Common code for open and creat.
111  * Check permissions, allocate an open file structure,
112  * and call the device open routine if any.
113  */
114 copen(mode, arg, fname)
115 	register int mode;
116 	int arg;
117 	caddr_t fname;
118 {
119 	register struct inode *ip;
120 	register struct file *fp;
121 	register struct nameidata *ndp = &u.u_nd;
122 	int indx;
123 
124 	fp = falloc();
125 	if (fp == NULL)
126 		return;
127 	indx = u.u_r.r_val1;
128 	ndp->ni_segflg = UIO_USERSPACE;
129 	ndp->ni_dirp = fname;
130 	if (mode&FCREAT) {
131 		if (mode & FEXCL)
132 			ndp->ni_nameiop = CREATE;
133 		else
134 			ndp->ni_nameiop = CREATE | FOLLOW;
135 		ip = namei(ndp);
136 		if (ip == NULL) {
137 			if (u.u_error)
138 				goto bad1;
139 			ip = maknode(arg&07777&(~ISVTX), ndp);
140 			if (ip == NULL)
141 				goto bad1;
142 			mode &= ~FTRUNC;
143 		} else {
144 			if (mode&FEXCL) {
145 				u.u_error = EEXIST;
146 				goto bad;
147 			}
148 			mode &= ~FCREAT;
149 		}
150 	} else {
151 		ndp->ni_nameiop = LOOKUP | FOLLOW;
152 		ip = namei(ndp);
153 		if (ip == NULL)
154 			goto bad1;
155 	}
156 	if ((ip->i_mode & IFMT) == IFSOCK) {
157 		u.u_error = EOPNOTSUPP;
158 		goto bad;
159 	}
160 	if ((mode&FCREAT) == 0) {
161 		if (mode&FREAD)
162 			if (access(ip, IREAD))
163 				goto bad;
164 		if (mode&(FWRITE|FTRUNC)) {
165 			if (access(ip, IWRITE))
166 				goto bad;
167 			if ((ip->i_mode&IFMT) == IFDIR) {
168 				u.u_error = EISDIR;
169 				goto bad;
170 			}
171 		}
172 	}
173 	if (mode&FTRUNC)
174 		itrunc(ip, (u_long)0);
175 	IUNLOCK(ip);
176 	fp->f_flag = mode&FMASK;
177 	fp->f_type = DTYPE_INODE;
178 	fp->f_ops = &inodeops;
179 	fp->f_data = (caddr_t)ip;
180 	if (setjmp(&u.u_qsave)) {
181 		if (u.u_error == 0)
182 			u.u_error = EINTR;
183 		u.u_ofile[indx] = NULL;
184 		closef(fp);
185 		return;
186 	}
187 	u.u_error = openi(ip, mode);
188 	if (u.u_error == 0)
189 		return;
190 	ILOCK(ip);
191 bad:
192 	iput(ip);
193 bad1:
194 	u.u_ofile[indx] = NULL;
195 	fp->f_count--;
196 }
197 
198 /*
199  * Mknod system call
200  */
201 mknod()
202 {
203 	register struct inode *ip;
204 	register struct a {
205 		char	*fname;
206 		int	fmode;
207 		int	dev;
208 	} *uap = (struct a *)u.u_ap;
209 	register struct nameidata *ndp = &u.u_nd;
210 
211 	if (!suser())
212 		return;
213 	ndp->ni_nameiop = CREATE;
214 	ndp->ni_segflg = UIO_USERSPACE;
215 	ndp->ni_dirp = uap->fname;
216 	ip = namei(ndp);
217 	if (ip != NULL) {
218 		u.u_error = EEXIST;
219 		goto out;
220 	}
221 	if (u.u_error)
222 		return;
223 	ip = maknode(uap->fmode, ndp);
224 	if (ip == NULL)
225 		return;
226 	switch (ip->i_mode & IFMT) {
227 
228 	case IFMT:	/* used by badsect to flag bad sectors */
229 	case IFCHR:
230 	case IFBLK:
231 		if (uap->dev) {
232 			/*
233 			 * Want to be able to use this to make badblock
234 			 * inodes, so don't truncate the dev number.
235 			 */
236 			ip->i_rdev = uap->dev;
237 			ip->i_flag |= IACC|IUPD|ICHG;
238 		}
239 	}
240 
241 out:
242 	iput(ip);
243 }
244 
245 /*
246  * link system call
247  */
248 link()
249 {
250 	register struct inode *ip, *xp;
251 	register struct a {
252 		char	*target;
253 		char	*linkname;
254 	} *uap = (struct a *)u.u_ap;
255 	register struct nameidata *ndp = &u.u_nd;
256 
257 	ndp->ni_nameiop = LOOKUP | FOLLOW;
258 	ndp->ni_segflg = UIO_USERSPACE;
259 	ndp->ni_dirp = uap->target;
260 	ip = namei(ndp);	/* well, this routine is doomed anyhow */
261 	if (ip == NULL)
262 		return;
263 	if ((ip->i_mode&IFMT) == IFDIR && !suser()) {
264 		iput(ip);
265 		return;
266 	}
267 	if (ip->i_nlink == LINK_MAX - 1) {
268 		u.u_error = EMLINK;
269 		iput(ip);
270 		return;
271 	}
272 	ip->i_nlink++;
273 	ip->i_flag |= ICHG;
274 	iupdat(ip, &time, &time, 1);
275 	IUNLOCK(ip);
276 	ndp->ni_nameiop = CREATE;
277 	ndp->ni_segflg = UIO_USERSPACE;
278 	ndp->ni_dirp = (caddr_t)uap->linkname;
279 	xp = namei(ndp);
280 	if (xp != NULL) {
281 		u.u_error = EEXIST;
282 		iput(xp);
283 		goto out;
284 	}
285 	if (u.u_error)
286 		goto out;
287 	if (ndp->ni_pdir->i_dev != ip->i_dev) {
288 		iput(ndp->ni_pdir);
289 		u.u_error = EXDEV;
290 		goto out;
291 	}
292 	u.u_error = direnter(ip, ndp);
293 out:
294 	if (u.u_error) {
295 		ip->i_nlink--;
296 		ip->i_flag |= ICHG;
297 	}
298 	irele(ip);
299 }
300 
301 /*
302  * symlink -- make a symbolic link
303  */
304 symlink()
305 {
306 	register struct a {
307 		char	*target;
308 		char	*linkname;
309 	} *uap = (struct a *)u.u_ap;
310 	register struct inode *ip;
311 	register char *tp;
312 	register c, nc;
313 	register struct nameidata *ndp = &u.u_nd;
314 
315 	tp = uap->target;
316 	nc = 0;
317 	while (c = fubyte(tp)) {
318 		if (c < 0) {
319 			u.u_error = EFAULT;
320 			return;
321 		}
322 		tp++;
323 		nc++;
324 	}
325 	ndp->ni_nameiop = CREATE;
326 	ndp->ni_segflg = UIO_USERSPACE;
327 	ndp->ni_dirp = uap->linkname;
328 	ip = namei(ndp);
329 	if (ip) {
330 		iput(ip);
331 		u.u_error = EEXIST;
332 		return;
333 	}
334 	if (u.u_error)
335 		return;
336 	ip = maknode(IFLNK | 0777, ndp);
337 	if (ip == NULL)
338 		return;
339 	u.u_error = rdwri(UIO_WRITE, ip, uap->target, nc, (off_t)0, 0,
340 	    (int *)0);
341 	/* handle u.u_error != 0 */
342 	iput(ip);
343 }
344 
345 /*
346  * Unlink system call.
347  * Hard to avoid races here, especially
348  * in unlinking directories.
349  */
350 unlink()
351 {
352 	struct a {
353 		char	*fname;
354 	} *uap = (struct a *)u.u_ap;
355 	register struct inode *ip, *dp;
356 	register struct nameidata *ndp = &u.u_nd;
357 
358 	ndp->ni_nameiop = DELETE | LOCKPARENT;
359 	ndp->ni_segflg = UIO_USERSPACE;
360 	ndp->ni_dirp = uap->fname;
361 	ip = namei(ndp);
362 	if (ip == NULL)
363 		return;
364 	dp = ndp->ni_pdir;
365 	if ((ip->i_mode&IFMT) == IFDIR && !suser())
366 		goto out;
367 	/*
368 	 * Don't unlink a mounted file.
369 	 */
370 	if (ip->i_dev != dp->i_dev) {
371 		u.u_error = EBUSY;
372 		goto out;
373 	}
374 	if (ip->i_flag&ITEXT)
375 		xrele(ip);	/* try once to free text */
376 	if (dirremove(ndp)) {
377 		ip->i_nlink--;
378 		ip->i_flag |= ICHG;
379 	}
380 out:
381 	if (dp == ip)
382 		irele(ip);
383 	else
384 		iput(ip);
385 	iput(dp);
386 }
387 
388 /*
389  * Seek system call
390  */
391 lseek()
392 {
393 	register struct file *fp;
394 	register struct a {
395 		int	fd;
396 		off_t	off;
397 		int	sbase;
398 	} *uap = (struct a *)u.u_ap;
399 
400 	GETF(fp, uap->fd);
401 	if (fp->f_type != DTYPE_INODE) {
402 		u.u_error = ESPIPE;
403 		return;
404 	}
405 	switch (uap->sbase) {
406 
407 	case L_INCR:
408 		fp->f_offset += uap->off;
409 		break;
410 
411 	case L_XTND:
412 		fp->f_offset = uap->off + ((struct inode *)fp->f_data)->i_size;
413 		break;
414 
415 	case L_SET:
416 		fp->f_offset = uap->off;
417 		break;
418 
419 	default:
420 		u.u_error = EINVAL;
421 		return;
422 	}
423 	u.u_r.r_off = fp->f_offset;
424 }
425 
426 /*
427  * Access system call
428  */
429 saccess()
430 {
431 	register svuid, svgid;
432 	register struct inode *ip;
433 	register struct a {
434 		char	*fname;
435 		int	fmode;
436 	} *uap = (struct a *)u.u_ap;
437 	register struct nameidata *ndp = &u.u_nd;
438 
439 	svuid = u.u_uid;
440 	svgid = u.u_gid;
441 	u.u_uid = u.u_ruid;
442 	u.u_gid = u.u_rgid;
443 	ndp->ni_nameiop = LOOKUP | FOLLOW;
444 	ndp->ni_segflg = UIO_USERSPACE;
445 	ndp->ni_dirp = uap->fname;
446 	ip = namei(ndp);
447 	if (ip != NULL) {
448 		if ((uap->fmode&R_OK) && access(ip, IREAD))
449 			goto done;
450 		if ((uap->fmode&W_OK) && access(ip, IWRITE))
451 			goto done;
452 		if ((uap->fmode&X_OK) && access(ip, IEXEC))
453 			goto done;
454 done:
455 		iput(ip);
456 	}
457 	u.u_uid = svuid;
458 	u.u_gid = svgid;
459 }
460 
461 /*
462  * Stat system call.  This version follows links.
463  */
464 stat()
465 {
466 
467 	stat1(FOLLOW);
468 }
469 
470 /*
471  * Lstat system call.  This version does not follow links.
472  */
473 lstat()
474 {
475 
476 	stat1(NOFOLLOW);
477 }
478 
479 stat1(follow)
480 	int follow;
481 {
482 	register struct inode *ip;
483 	register struct a {
484 		char	*fname;
485 		struct stat *ub;
486 	} *uap = (struct a *)u.u_ap;
487 	struct stat sb;
488 	register struct nameidata *ndp = &u.u_nd;
489 
490 	ndp->ni_nameiop = LOOKUP | follow;
491 	ndp->ni_segflg = UIO_USERSPACE;
492 	ndp->ni_dirp = uap->fname;
493 	ip = namei(ndp);
494 	if (ip == NULL)
495 		return;
496 	(void) ino_stat(ip, &sb);
497 	iput(ip);
498 	u.u_error = copyout((caddr_t)&sb, (caddr_t)uap->ub, sizeof (sb));
499 }
500 
501 /*
502  * Return target name of a symbolic link
503  */
504 readlink()
505 {
506 	register struct inode *ip;
507 	register struct a {
508 		char	*name;
509 		char	*buf;
510 		int	count;
511 	} *uap = (struct a *)u.u_ap;
512 	register struct nameidata *ndp = &u.u_nd;
513 	int resid;
514 
515 	ndp->ni_nameiop = LOOKUP;
516 	ndp->ni_segflg = UIO_USERSPACE;
517 	ndp->ni_dirp = uap->name;
518 	ip = namei(ndp);
519 	if (ip == NULL)
520 		return;
521 	if ((ip->i_mode&IFMT) != IFLNK) {
522 		u.u_error = EINVAL;
523 		goto out;
524 	}
525 	u.u_error = rdwri(UIO_READ, ip, uap->buf, uap->count, (off_t)0, 0,
526 	    &resid);
527 out:
528 	iput(ip);
529 	u.u_r.r_val1 = uap->count - resid;
530 }
531 
532 /*
533  * Change mode of a file given path name.
534  */
535 chmod()
536 {
537 	struct inode *ip;
538 	struct a {
539 		char	*fname;
540 		int	fmode;
541 	} *uap = (struct a *)u.u_ap;
542 
543 	if ((ip = owner(uap->fname, FOLLOW)) == NULL)
544 		return;
545 	u.u_error = chmod1(ip, uap->fmode);
546 	iput(ip);
547 }
548 
549 /*
550  * Change mode of a file given a file descriptor.
551  */
552 fchmod()
553 {
554 	struct a {
555 		int	fd;
556 		int	fmode;
557 	} *uap = (struct a *)u.u_ap;
558 	register struct inode *ip;
559 	register struct file *fp;
560 
561 	fp = getinode(uap->fd);
562 	if (fp == NULL)
563 		return;
564 	ip = (struct inode *)fp->f_data;
565 	if (u.u_uid != ip->i_uid && !suser())
566 		return;
567 	ILOCK(ip);
568 	u.u_error = chmod1(ip, uap->fmode);
569 	IUNLOCK(ip);
570 }
571 
572 /*
573  * Change the mode on a file.
574  * Inode must be locked before calling.
575  */
576 chmod1(ip, mode)
577 	register struct inode *ip;
578 	register int mode;
579 {
580 
581 	if (ip->i_fs->fs_ronly)
582 		return (EROFS);
583 	ip->i_mode &= ~07777;
584 	if (u.u_uid) {
585 		if ((ip->i_mode & IFMT) != IFDIR)
586 			mode &= ~ISVTX;
587 		if (!groupmember(ip->i_gid))
588 			mode &= ~ISGID;
589 	}
590 	ip->i_mode |= mode&07777;
591 	ip->i_flag |= ICHG;
592 	if (ip->i_flag&ITEXT && (ip->i_mode&ISVTX)==0)
593 		xrele(ip);
594 	return (0);
595 }
596 
597 /*
598  * Set ownership given a path name.
599  */
600 chown()
601 {
602 	struct inode *ip;
603 	struct a {
604 		char	*fname;
605 		int	uid;
606 		int	gid;
607 	} *uap = (struct a *)u.u_ap;
608 	register struct nameidata *ndp = &u.u_nd;
609 
610 	ndp->ni_nameiop = LOOKUP | NOFOLLOW;
611 	ndp->ni_segflg = UIO_USERSPACE;
612 	ndp->ni_dirp = uap->fname;
613 	ip = namei(ndp);
614 	if (ip == NULL)
615 		return;
616 	u.u_error = chown1(ip, uap->uid, uap->gid);
617 	iput(ip);
618 }
619 
620 /*
621  * Set ownership given a file descriptor.
622  */
623 fchown()
624 {
625 	struct a {
626 		int	fd;
627 		int	uid;
628 		int	gid;
629 	} *uap = (struct a *)u.u_ap;
630 	register struct inode *ip;
631 	register struct file *fp;
632 
633 	fp = getinode(uap->fd);
634 	if (fp == NULL)
635 		return;
636 	ip = (struct inode *)fp->f_data;
637 	ILOCK(ip);
638 	u.u_error = chown1(ip, uap->uid, uap->gid);
639 	IUNLOCK(ip);
640 }
641 
642 /*
643  * Perform chown operation on inode ip;
644  * inode must be locked prior to call.
645  */
646 chown1(ip, uid, gid)
647 	register struct inode *ip;
648 	int uid, gid;
649 {
650 #ifdef QUOTA
651 	register long change;
652 #endif
653 
654 	if (ip->i_fs->fs_ronly)
655 		return (EROFS);
656 	if (uid == -1)
657 		uid = ip->i_uid;
658 	if (gid == -1)
659 		gid = ip->i_gid;
660 	/*
661 	 * If we don't own the file, are trying to change the owner
662 	 * of the file, or are not a member of the target group,
663 	 * the caller must be superuser or the call fails.
664 	 */
665 	if ((u.u_uid != ip->i_uid || uid != ip->i_uid ||
666 	    !groupmember((gid_t)gid)) && !suser())
667 		return (u.u_error);
668 #ifdef QUOTA
669 	if (ip->i_uid == uid)		/* this just speeds things a little */
670 		change = 0;
671 	else
672 		change = ip->i_blocks;
673 	(void) chkdq(ip, -change, 1);
674 	(void) chkiq(ip->i_dev, ip, ip->i_uid, 1);
675 	dqrele(ip->i_dquot);
676 #endif
677 	ip->i_uid = uid;
678 	ip->i_gid = gid;
679 	ip->i_flag |= ICHG;
680 	if (u.u_ruid != 0)
681 		ip->i_mode &= ~(ISUID|ISGID);
682 #ifdef QUOTA
683 	ip->i_dquot = inoquota(ip);
684 	(void) chkdq(ip, change, 1);
685 	(void) chkiq(ip->i_dev, (struct inode *)NULL, (uid_t)uid, 1);
686 	return (u.u_error);		/* should == 0 ALWAYS !! */
687 #else
688 	return (0);
689 #endif
690 }
691 
692 utimes()
693 {
694 	register struct a {
695 		char	*fname;
696 		struct	timeval *tptr;
697 	} *uap = (struct a *)u.u_ap;
698 	register struct inode *ip;
699 	struct timeval tv[2];
700 
701 	if ((ip = owner(uap->fname, FOLLOW)) == NULL)
702 		return;
703 	if (ip->i_fs->fs_ronly) {
704 		u.u_error = EROFS;
705 		iput(ip);
706 		return;
707 	}
708 	u.u_error = copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof (tv));
709 	if (u.u_error == 0) {
710 		ip->i_flag |= IACC|IUPD|ICHG;
711 		iupdat(ip, &tv[0], &tv[1], 0);
712 	}
713 	iput(ip);
714 }
715 
716 /*
717  * Flush any pending I/O.
718  */
719 sync()
720 {
721 
722 	update();
723 }
724 
725 /*
726  * Truncate a file given its path name.
727  */
728 truncate()
729 {
730 	struct a {
731 		char	*fname;
732 		off_t	length;
733 	} *uap = (struct a *)u.u_ap;
734 	struct inode *ip;
735 	register struct nameidata *ndp = &u.u_nd;
736 
737 	ndp->ni_nameiop = LOOKUP | FOLLOW;
738 	ndp->ni_segflg = UIO_USERSPACE;
739 	ndp->ni_dirp = uap->fname;
740 	ip = namei(ndp);
741 	if (ip == NULL)
742 		return;
743 	if (access(ip, IWRITE))
744 		goto bad;
745 	if ((ip->i_mode&IFMT) == IFDIR) {
746 		u.u_error = EISDIR;
747 		goto bad;
748 	}
749 	itrunc(ip, (u_long)uap->length);
750 bad:
751 	iput(ip);
752 }
753 
754 /*
755  * Truncate a file given a file descriptor.
756  */
757 ftruncate()
758 {
759 	struct a {
760 		int	fd;
761 		off_t	length;
762 	} *uap = (struct a *)u.u_ap;
763 	struct inode *ip;
764 	struct file *fp;
765 
766 	fp = getinode(uap->fd);
767 	if (fp == NULL)
768 		return;
769 	if ((fp->f_flag&FWRITE) == 0) {
770 		u.u_error = EINVAL;
771 		return;
772 	}
773 	ip = (struct inode *)fp->f_data;
774 	ILOCK(ip);
775 	itrunc(ip, (u_long)uap->length);
776 	IUNLOCK(ip);
777 }
778 
779 /*
780  * Synch an open file.
781  */
782 fsync()
783 {
784 	struct a {
785 		int	fd;
786 	} *uap = (struct a *)u.u_ap;
787 	struct inode *ip;
788 	struct file *fp;
789 
790 	fp = getinode(uap->fd);
791 	if (fp == NULL)
792 		return;
793 	ip = (struct inode *)fp->f_data;
794 	ILOCK(ip);
795 	if (fp->f_flag&FWRITE)
796 		ip->i_flag |= ICHG;
797 	syncip(ip);
798 	IUNLOCK(ip);
799 }
800 
801 /*
802  * Rename system call.
803  * 	rename("foo", "bar");
804  * is essentially
805  *	unlink("bar");
806  *	link("foo", "bar");
807  *	unlink("foo");
808  * but ``atomically''.  Can't do full commit without saving state in the
809  * inode on disk which isn't feasible at this time.  Best we can do is
810  * always guarantee the target exists.
811  *
812  * Basic algorithm is:
813  *
814  * 1) Bump link count on source while we're linking it to the
815  *    target.  This also insure the inode won't be deleted out
816  *    from underneath us while we work (it may be truncated by
817  *    a concurrent `trunc' or `open' for creation).
818  * 2) Link source to destination.  If destination already exists,
819  *    delete it first.
820  * 3) Unlink source reference to inode if still around. If a
821  *    directory was moved and the parent of the destination
822  *    is different from the source, patch the ".." entry in the
823  *    directory.
824  *
825  * Source and destination must either both be directories, or both
826  * not be directories.  If target is a directory, it must be empty.
827  */
828 rename()
829 {
830 	struct a {
831 		char	*from;
832 		char	*to;
833 	} *uap = (struct a *)u.u_ap;
834 	register struct inode *ip, *xp, *dp;
835 	struct dirtemplate dirbuf;
836 	int doingdirectory = 0, oldparent = 0, newparent = 0;
837 	register struct nameidata *ndp = &u.u_nd;
838 	int error = 0;
839 
840 	ndp->ni_nameiop = DELETE | LOCKPARENT;
841 	ndp->ni_segflg = UIO_USERSPACE;
842 	ndp->ni_dirp = uap->from;
843 	ip = namei(ndp);
844 	if (ip == NULL)
845 		return;
846 	dp = ndp->ni_pdir;
847 	if ((ip->i_mode&IFMT) == IFDIR) {
848 		register struct direct *d;
849 
850 		d = &ndp->ni_dent;
851 		/*
852 		 * Avoid ".", "..", and aliases of "." for obvious reasons.
853 		 */
854 		if ((d->d_namlen == 1 && d->d_name[0] == '.') ||
855 		    (d->d_namlen == 2 && bcmp(d->d_name, "..", 2) == 0) ||
856 		    (dp == ip) || (ip->i_flag & IRENAME)) {
857 			iput(dp);
858 			if (dp == ip)
859 				irele(ip);
860 			else
861 				iput(ip);
862 			u.u_error = EINVAL;
863 			return;
864 		}
865 		ip->i_flag |= IRENAME;
866 		oldparent = dp->i_number;
867 		doingdirectory++;
868 	}
869 	iput(dp);
870 
871 	/*
872 	 * 1) Bump link count while we're moving stuff
873 	 *    around.  If we crash somewhere before
874 	 *    completing our work, the link count
875 	 *    may be wrong, but correctable.
876 	 */
877 	ip->i_nlink++;
878 	ip->i_flag |= ICHG;
879 	iupdat(ip, &time, &time, 1);
880 	IUNLOCK(ip);
881 
882 	/*
883 	 * When the target exists, both the directory
884 	 * and target inodes are returned locked.
885 	 */
886 	ndp->ni_nameiop = CREATE | LOCKPARENT | NOCACHE;
887 	ndp->ni_dirp = (caddr_t)uap->to;
888 	xp = namei(ndp);
889 	if (u.u_error) {
890 		error = u.u_error;
891 		goto out;
892 	}
893 	dp = ndp->ni_pdir;
894 	/*
895 	 * If ".." must be changed (ie the directory gets a new
896 	 * parent) then the source directory must not be in the
897 	 * directory heirarchy above the target, as this would
898 	 * orphan everything below the source directory. Also
899 	 * the user must have write permission in the source so
900 	 * as to be able to change "..". We must repeat the call
901 	 * to namei, as the parent directory is unlocked by the
902 	 * call to checkpath().
903 	 */
904 	if (oldparent != dp->i_number)
905 		newparent = dp->i_number;
906 	if (doingdirectory && newparent) {
907 		if (access(ip, IWRITE))
908 			goto bad;
909 		do {
910 			dp = ndp->ni_pdir;
911 			if (xp != NULL)
912 				iput(xp);
913 			u.u_error = checkpath(ip, dp);
914 			if (u.u_error)
915 				goto out;
916 			xp = namei(ndp);
917 			if (u.u_error) {
918 				error = u.u_error;
919 				goto out;
920 			}
921 		} while (dp != ndp->ni_pdir);
922 	}
923 	/*
924 	 * 2) If target doesn't exist, link the target
925 	 *    to the source and unlink the source.
926 	 *    Otherwise, rewrite the target directory
927 	 *    entry to reference the source inode and
928 	 *    expunge the original entry's existence.
929 	 */
930 	if (xp == NULL) {
931 		if (dp->i_dev != ip->i_dev) {
932 			error = EXDEV;
933 			goto bad;
934 		}
935 		/*
936 		 * Account for ".." in new directory.
937 		 * When source and destination have the same
938 		 * parent we don't fool with the link count.
939 		 */
940 		if (doingdirectory && newparent) {
941 			dp->i_nlink++;
942 			dp->i_flag |= ICHG;
943 			iupdat(dp, &time, &time, 1);
944 		}
945 		error = direnter(ip, ndp);
946 		if (error)
947 			goto out;
948 	} else {
949 		if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev) {
950 			error = EXDEV;
951 			goto bad;
952 		}
953 		/*
954 		 * Short circuit rename(foo, foo).
955 		 */
956 		if (xp->i_number == ip->i_number)
957 			goto bad;
958 		/*
959 		 * If the parent directory is "sticky", then the user must
960 		 * own the parent directory, or the destination of the rename,
961 		 * otherwise the destination may not be changed (except by
962 		 * root). This implements append-only directories.
963 		 */
964 		if ((dp->i_mode & ISVTX) && u.u_uid != 0 &&
965 		    u.u_uid != dp->i_uid && xp->i_uid != u.u_uid) {
966 			error = EPERM;
967 			goto bad;
968 		}
969 		/*
970 		 * Target must be empty if a directory
971 		 * and have no links to it.
972 		 * Also, insure source and target are
973 		 * compatible (both directories, or both
974 		 * not directories).
975 		 */
976 		if ((xp->i_mode&IFMT) == IFDIR) {
977 			if (!dirempty(xp, dp->i_number) || xp->i_nlink > 2) {
978 				error = ENOTEMPTY;
979 				goto bad;
980 			}
981 			if (!doingdirectory) {
982 				error = ENOTDIR;
983 				goto bad;
984 			}
985 			cacheinval(dp);
986 		} else if (doingdirectory) {
987 			error = EISDIR;
988 			goto bad;
989 		}
990 		dirrewrite(dp, ip, ndp);
991 		if (u.u_error) {
992 			error = u.u_error;
993 			goto bad1;
994 		}
995 		/*
996 		 * Adjust the link count of the target to
997 		 * reflect the dirrewrite above.  If this is
998 		 * a directory it is empty and there are
999 		 * no links to it, so we can squash the inode and
1000 		 * any space associated with it.  We disallowed
1001 		 * renaming over top of a directory with links to
1002 		 * it above, as the remaining link would point to
1003 		 * a directory without "." or ".." entries.
1004 		 */
1005 		xp->i_nlink--;
1006 		if (doingdirectory) {
1007 			if (--xp->i_nlink != 0)
1008 				panic("rename: linked directory");
1009 			itrunc(xp, (u_long)0);
1010 		}
1011 		xp->i_flag |= ICHG;
1012 		iput(xp);
1013 		xp = NULL;
1014 	}
1015 
1016 	/*
1017 	 * 3) Unlink the source.
1018 	 */
1019 	ndp->ni_nameiop = DELETE | LOCKPARENT;
1020 	ndp->ni_segflg = UIO_USERSPACE;
1021 	ndp->ni_dirp = uap->from;
1022 	xp = namei(ndp);
1023 	if (xp != NULL)
1024 		dp = ndp->ni_pdir;
1025 	else
1026 		dp = NULL;
1027 	/*
1028 	 * Insure that the directory entry still exists and has not
1029 	 * changed while the new name has been entered. If the source is
1030 	 * a file then the entry may have been unlinked or renamed. In
1031 	 * either case there is no further work to be done. If the source
1032 	 * is a directory then it cannot have been rmdir'ed; its link
1033 	 * count of three would cause a rmdir to fail with ENOTEMPTY.
1034 	 * The IRENAME flag insures that it cannot be moved by another
1035 	 * rename.
1036 	 */
1037 	if (xp != ip) {
1038 		if (doingdirectory)
1039 			panic("rename: lost dir entry");
1040 	} else {
1041 		/*
1042 		 * If the source is a directory with a
1043 		 * new parent, the link count of the old
1044 		 * parent directory must be decremented
1045 		 * and ".." set to point to the new parent.
1046 		 */
1047 		if (doingdirectory && newparent) {
1048 			dp->i_nlink--;
1049 			dp->i_flag |= ICHG;
1050 			error = rdwri(UIO_READ, xp, (caddr_t)&dirbuf,
1051 				sizeof (struct dirtemplate), (off_t)0, 1,
1052 				(int *)0);
1053 			if (error == 0) {
1054 				if (dirbuf.dotdot_namlen != 2 ||
1055 				    dirbuf.dotdot_name[0] != '.' ||
1056 				    dirbuf.dotdot_name[1] != '.') {
1057 					printf("rename: mangled dir\n");
1058 				} else {
1059 					dirbuf.dotdot_ino = newparent;
1060 					(void) rdwri(UIO_WRITE, xp,
1061 					    (caddr_t)&dirbuf,
1062 					    sizeof (struct dirtemplate),
1063 					    (off_t)0, 1, (int *)0);
1064 					cacheinval(dp);
1065 				}
1066 			}
1067 		}
1068 		if (dirremove(ndp)) {
1069 			xp->i_nlink--;
1070 			xp->i_flag |= ICHG;
1071 		}
1072 		xp->i_flag &= ~IRENAME;
1073 		if (error == 0)		/* XXX conservative */
1074 			error = u.u_error;
1075 	}
1076 	if (dp)
1077 		iput(dp);
1078 	if (xp)
1079 		iput(xp);
1080 	irele(ip);
1081 	if (error)
1082 		u.u_error = error;
1083 	return;
1084 
1085 bad:
1086 	iput(dp);
1087 bad1:
1088 	if (xp)
1089 		iput(xp);
1090 out:
1091 	ip->i_nlink--;
1092 	ip->i_flag |= ICHG;
1093 	irele(ip);
1094 	if (error)
1095 		u.u_error = error;
1096 }
1097 
1098 /*
1099  * Make a new file.
1100  */
1101 struct inode *
1102 maknode(mode, ndp)
1103 	int mode;
1104 	register struct nameidata *ndp;
1105 {
1106 	register struct inode *ip;
1107 	register struct inode *pdir = ndp->ni_pdir;
1108 	ino_t ipref;
1109 
1110 	if ((mode & IFMT) == IFDIR)
1111 		ipref = dirpref(pdir->i_fs);
1112 	else
1113 		ipref = pdir->i_number;
1114 	ip = ialloc(pdir, ipref, mode);
1115 	if (ip == NULL) {
1116 		iput(pdir);
1117 		return (NULL);
1118 	}
1119 #ifdef QUOTA
1120 	if (ip->i_dquot != NODQUOT)
1121 		panic("maknode: dquot");
1122 #endif
1123 	ip->i_flag |= IACC|IUPD|ICHG;
1124 	if ((mode & IFMT) == 0)
1125 		mode |= IFREG;
1126 	ip->i_mode = mode & ~u.u_cmask;
1127 	ip->i_nlink = 1;
1128 	ip->i_uid = u.u_uid;
1129 	ip->i_gid = pdir->i_gid;
1130 	if (ip->i_mode & ISGID && !groupmember(ip->i_gid) && !suser())
1131 		ip->i_mode &= ~ISGID;
1132 #ifdef QUOTA
1133 	ip->i_dquot = inoquota(ip);
1134 #endif
1135 
1136 	/*
1137 	 * Make sure inode goes to disk before directory entry.
1138 	 */
1139 	iupdat(ip, &time, &time, 1);
1140 	u.u_error = direnter(ip, ndp);
1141 	if (u.u_error) {
1142 		/*
1143 		 * Write error occurred trying to update directory
1144 		 * so must deallocate the inode.
1145 		 */
1146 		ip->i_nlink = 0;
1147 		ip->i_flag |= ICHG;
1148 		iput(ip);
1149 		return (NULL);
1150 	}
1151 	return (ip);
1152 }
1153 
1154 /*
1155  * A virgin directory (no blushing please).
1156  */
1157 struct dirtemplate mastertemplate = {
1158 	0, 12, 1, ".",
1159 	0, DIRBLKSIZ - 12, 2, ".."
1160 };
1161 
1162 /*
1163  * Mkdir system call
1164  */
1165 mkdir()
1166 {
1167 	struct a {
1168 		char	*name;
1169 		int	dmode;
1170 	} *uap = (struct a *)u.u_ap;
1171 	register struct inode *ip, *dp;
1172 	struct dirtemplate dirtemplate;
1173 	register struct nameidata *ndp = &u.u_nd;
1174 
1175 	ndp->ni_nameiop = CREATE;
1176 	ndp->ni_segflg = UIO_USERSPACE;
1177 	ndp->ni_dirp = uap->name;
1178 	ip = namei(ndp);
1179 	if (u.u_error)
1180 		return;
1181 	if (ip != NULL) {
1182 		iput(ip);
1183 		u.u_error = EEXIST;
1184 		return;
1185 	}
1186 	dp = ndp->ni_pdir;
1187 	uap->dmode &= 0777;
1188 	uap->dmode |= IFDIR;
1189 	/*
1190 	 * Must simulate part of maknode here
1191 	 * in order to acquire the inode, but
1192 	 * not have it entered in the parent
1193 	 * directory.  The entry is made later
1194 	 * after writing "." and ".." entries out.
1195 	 */
1196 	ip = ialloc(dp, dirpref(dp->i_fs), uap->dmode);
1197 	if (ip == NULL) {
1198 		iput(dp);
1199 		return;
1200 	}
1201 #ifdef QUOTA
1202 	if (ip->i_dquot != NODQUOT)
1203 		panic("mkdir: dquot");
1204 #endif
1205 	ip->i_flag |= IACC|IUPD|ICHG;
1206 	ip->i_mode = uap->dmode & ~u.u_cmask;
1207 	ip->i_nlink = 2;
1208 	ip->i_uid = u.u_uid;
1209 	ip->i_gid = dp->i_gid;
1210 #ifdef QUOTA
1211 	ip->i_dquot = inoquota(ip);
1212 #endif
1213 	iupdat(ip, &time, &time, 1);
1214 
1215 	/*
1216 	 * Bump link count in parent directory
1217 	 * to reflect work done below.  Should
1218 	 * be done before reference is created
1219 	 * so reparation is possible if we crash.
1220 	 */
1221 	dp->i_nlink++;
1222 	dp->i_flag |= ICHG;
1223 	iupdat(dp, &time, &time, 1);
1224 
1225 	/*
1226 	 * Initialize directory with "."
1227 	 * and ".." from static template.
1228 	 */
1229 	dirtemplate = mastertemplate;
1230 	dirtemplate.dot_ino = ip->i_number;
1231 	dirtemplate.dotdot_ino = dp->i_number;
1232 	u.u_error = rdwri(UIO_WRITE, ip, (caddr_t)&dirtemplate,
1233 		sizeof (dirtemplate), (off_t)0, 1, (int *)0);
1234 	if (u.u_error) {
1235 		dp->i_nlink--;
1236 		dp->i_flag |= ICHG;
1237 		goto bad;
1238 	}
1239 	if (DIRBLKSIZ > ip->i_fs->fs_fsize)
1240 		panic("mkdir: blksize");     /* XXX - should grow with bmap() */
1241 	else
1242 		ip->i_size = DIRBLKSIZ;
1243 	/*
1244 	 * Directory all set up, now
1245 	 * install the entry for it in
1246 	 * the parent directory.
1247 	 */
1248 	u.u_error = direnter(ip, ndp);
1249 	dp = NULL;
1250 	if (u.u_error) {
1251 		ndp->ni_nameiop = LOOKUP | NOCACHE;
1252 		ndp->ni_segflg = UIO_USERSPACE;
1253 		ndp->ni_dirp = uap->name;
1254 		dp = namei(ndp);
1255 		if (dp) {
1256 			dp->i_nlink--;
1257 			dp->i_flag |= ICHG;
1258 		}
1259 	}
1260 bad:
1261 	/*
1262 	 * No need to do an explicit itrunc here,
1263 	 * irele will do this for us because we set
1264 	 * the link count to 0.
1265 	 */
1266 	if (u.u_error) {
1267 		ip->i_nlink = 0;
1268 		ip->i_flag |= ICHG;
1269 	}
1270 	if (dp)
1271 		iput(dp);
1272 	iput(ip);
1273 }
1274 
1275 /*
1276  * Rmdir system call.
1277  */
1278 rmdir()
1279 {
1280 	struct a {
1281 		char	*name;
1282 	} *uap = (struct a *)u.u_ap;
1283 	register struct inode *ip, *dp;
1284 	register struct nameidata *ndp = &u.u_nd;
1285 
1286 	ndp->ni_nameiop = DELETE | LOCKPARENT;
1287 	ndp->ni_segflg = UIO_USERSPACE;
1288 	ndp->ni_dirp = uap->name;
1289 	ip = namei(ndp);
1290 	if (ip == NULL)
1291 		return;
1292 	dp = ndp->ni_pdir;
1293 	/*
1294 	 * No rmdir "." please.
1295 	 */
1296 	if (dp == ip) {
1297 		irele(dp);
1298 		iput(ip);
1299 		u.u_error = EINVAL;
1300 		return;
1301 	}
1302 	if ((ip->i_mode&IFMT) != IFDIR) {
1303 		u.u_error = ENOTDIR;
1304 		goto out;
1305 	}
1306 	/*
1307 	 * Don't remove a mounted on directory.
1308 	 */
1309 	if (ip->i_dev != dp->i_dev) {
1310 		u.u_error = EBUSY;
1311 		goto out;
1312 	}
1313 	/*
1314 	 * Verify the directory is empty (and valid).
1315 	 * (Rmdir ".." won't be valid since
1316 	 *  ".." will contain a reference to
1317 	 *  the current directory and thus be
1318 	 *  non-empty.)
1319 	 */
1320 	if (ip->i_nlink != 2 || !dirempty(ip, dp->i_number)) {
1321 		u.u_error = ENOTEMPTY;
1322 		goto out;
1323 	}
1324 	/*
1325 	 * Delete reference to directory before purging
1326 	 * inode.  If we crash in between, the directory
1327 	 * will be reattached to lost+found,
1328 	 */
1329 	if (dirremove(ndp) == 0)
1330 		goto out;
1331 	dp->i_nlink--;
1332 	dp->i_flag |= ICHG;
1333 	cacheinval(dp);
1334 	iput(dp);
1335 	dp = NULL;
1336 	/*
1337 	 * Truncate inode.  The only stuff left
1338 	 * in the directory is "." and "..".  The
1339 	 * "." reference is inconsequential since
1340 	 * we're quashing it.  The ".." reference
1341 	 * has already been adjusted above.  We've
1342 	 * removed the "." reference and the reference
1343 	 * in the parent directory, but there may be
1344 	 * other hard links so decrement by 2 and
1345 	 * worry about them later.
1346 	 */
1347 	ip->i_nlink -= 2;
1348 	itrunc(ip, (u_long)0);
1349 	cacheinval(ip);
1350 out:
1351 	if (dp)
1352 		iput(dp);
1353 	iput(ip);
1354 }
1355 
1356 struct file *
1357 getinode(fdes)
1358 	int fdes;
1359 {
1360 	struct file *fp;
1361 
1362 	if ((unsigned)fdes >= NOFILE || (fp = u.u_ofile[fdes]) == NULL) {
1363 		u.u_error = EBADF;
1364 		return ((struct file *)0);
1365 	}
1366 	if (fp->f_type != DTYPE_INODE) {
1367 		u.u_error = EINVAL;
1368 		return ((struct file *)0);
1369 	}
1370 	return (fp);
1371 }
1372 
1373 /*
1374  * mode mask for creation of files
1375  */
1376 umask()
1377 {
1378 	register struct a {
1379 		int	mask;
1380 	} *uap = (struct a *)u.u_ap;
1381 
1382 	u.u_r.r_val1 = u.u_cmask;
1383 	u.u_cmask = uap->mask & 07777;
1384 }
1385