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