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