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