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