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