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