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