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