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