xref: /csrg-svn/sys/kern/vfs_syscalls.c (revision 7142)
1*7142Smckusick /*	vfs_syscalls.c	4.26	82/06/10	*/
237Sbill 
36574Smckusic #ifdef SIMFS
46574Smckusic #include "../h/sysrenam.h"
56574Smckusic #endif
637Sbill #include "../h/param.h"
737Sbill #include "../h/systm.h"
837Sbill #include "../h/dir.h"
937Sbill #include "../h/user.h"
106254Sroot #include "../h/file.h"
116574Smckusic #include "../h/stat.h"
1237Sbill #include "../h/inode.h"
136574Smckusic #include "../h/fs.h"
146254Sroot #include "../h/buf.h"
156254Sroot #include "../h/proc.h"
166254Sroot #include "../h/inline.h"
1737Sbill 
186254Sroot chdir()
196254Sroot {
206254Sroot 
216254Sroot 	chdirec(&u.u_cdir);
226254Sroot }
236254Sroot 
246254Sroot chroot()
256254Sroot {
266254Sroot 
276254Sroot 	if (suser())
286254Sroot 		chdirec(&u.u_rdir);
296254Sroot }
306254Sroot 
316254Sroot chdirec(ipp)
326254Sroot register struct inode **ipp;
336254Sroot {
346254Sroot 	register struct inode *ip;
356254Sroot 	struct a {
366254Sroot 		char	*fname;
376254Sroot 	};
386254Sroot 
396254Sroot 	ip = namei(uchar, 0, 1);
406254Sroot 	if(ip == NULL)
416254Sroot 		return;
426254Sroot 	if((ip->i_mode&IFMT) != IFDIR) {
436254Sroot 		u.u_error = ENOTDIR;
446254Sroot 		goto bad;
456254Sroot 	}
466254Sroot 	if(access(ip, IEXEC))
476254Sroot 		goto bad;
487122Smckusick 	iunlock(ip);
49*7142Smckusick 	if (*ipp)
50*7142Smckusick 		irele(*ipp);
516254Sroot 	*ipp = ip;
526254Sroot 	return;
536254Sroot 
546254Sroot bad:
556254Sroot 	iput(ip);
566254Sroot }
576254Sroot 
5837Sbill /*
596254Sroot  * Open system call.
606254Sroot  */
616254Sroot open()
626254Sroot {
636254Sroot 	register struct inode *ip;
646254Sroot 	register struct a {
656254Sroot 		char	*fname;
666254Sroot 		int	rwmode;
676254Sroot 	} *uap;
686254Sroot 
696254Sroot 	uap = (struct a *)u.u_ap;
706254Sroot 	ip = namei(uchar, 0, 1);
716254Sroot 	if (ip == NULL)
726254Sroot 		return;
736254Sroot 	open1(ip, ++uap->rwmode, 0);
746254Sroot }
756254Sroot 
766254Sroot /*
776254Sroot  * Creat system call.
786254Sroot  */
796254Sroot creat()
806254Sroot {
816254Sroot 	register struct inode *ip;
826254Sroot 	register struct a {
836254Sroot 		char	*fname;
846254Sroot 		int	fmode;
856254Sroot 	} *uap;
866254Sroot 
876254Sroot 	uap = (struct a *)u.u_ap;
886254Sroot 	ip = namei(uchar, 1, 1);
896254Sroot 	if (ip == NULL) {
906254Sroot 		if (u.u_error)
916254Sroot 			return;
926254Sroot 		ip = maknode(uap->fmode&07777&(~ISVTX));
936254Sroot 		if (ip==NULL)
946254Sroot 			return;
956254Sroot 		open1(ip, FWRITE, 2);
966254Sroot 	} else
976254Sroot 		open1(ip, FWRITE, 1);
986254Sroot }
996254Sroot 
1006254Sroot /*
1016254Sroot  * Common code for open and creat.
1026254Sroot  * Check permissions, allocate an open file structure,
1036254Sroot  * and call the device open routine if any.
1046254Sroot  */
1056254Sroot open1(ip, mode, trf)
1066254Sroot 	register struct inode *ip;
1076254Sroot 	register mode;
1086254Sroot {
1096254Sroot 	register struct file *fp;
1106254Sroot 	int i;
1116254Sroot 
1126254Sroot 	if (trf != 2) {
1136254Sroot 		if (mode&FREAD)
1146254Sroot 			(void) access(ip, IREAD);
1156254Sroot 		if (mode&FWRITE) {
1166254Sroot 			(void) access(ip, IWRITE);
1176254Sroot 			if ((ip->i_mode&IFMT) == IFDIR)
1186254Sroot 				u.u_error = EISDIR;
1196254Sroot 		}
1206254Sroot 	}
121*7142Smckusick 	if (u.u_error) {
122*7142Smckusick 		iput(ip);
123*7142Smckusick 		return;
124*7142Smckusick 	}
1256254Sroot 	if (trf == 1)
1266254Sroot 		itrunc(ip);
1277122Smckusick 	iunlock(ip);
1286254Sroot 	if ((fp = falloc()) == NULL)
1296254Sroot 		goto out;
1306254Sroot 	fp->f_flag = mode&(FREAD|FWRITE);
1316254Sroot 	i = u.u_r.r_val1;
1326254Sroot 	fp->f_inode = ip;
1336254Sroot 	openi(ip, mode&(FREAD|FWRITE));
1346254Sroot 	if (u.u_error == 0)
1356254Sroot 		return;
1366254Sroot 	u.u_ofile[i] = NULL;
1376254Sroot 	fp->f_count--;
1386254Sroot out:
139*7142Smckusick 	irele(ip);
1406254Sroot }
1416254Sroot 
1426254Sroot /*
1436254Sroot  * Mknod system call
1446254Sroot  */
1456254Sroot mknod()
1466254Sroot {
1476254Sroot 	register struct inode *ip;
1486254Sroot 	register struct a {
1496254Sroot 		char	*fname;
1506254Sroot 		int	fmode;
1516254Sroot 		int	dev;
1526254Sroot 	} *uap;
1536254Sroot 
1546254Sroot 	uap = (struct a *)u.u_ap;
1556254Sroot 	if (suser()) {
1566254Sroot 		ip = namei(uchar, 1, 0);
1576254Sroot 		if (ip != NULL) {
1586254Sroot 			u.u_error = EEXIST;
1596254Sroot 			goto out;
1606254Sroot 		}
1616254Sroot 	}
1626254Sroot 	if (u.u_error)
1636254Sroot 		return;
1646254Sroot 	ip = maknode(uap->fmode);
1656254Sroot 	if (ip == NULL)
1666254Sroot 		return;
1676254Sroot 	if (uap->dev) {
1686254Sroot 		/*
1696254Sroot 		 * Want to be able to use this to make badblock
1706254Sroot 		 * inodes, so don't truncate the dev number.
1716254Sroot 		 */
1726574Smckusic 		ip->i_rdev = uap->dev;
1736254Sroot 		ip->i_flag |= IACC|IUPD|ICHG;
1746254Sroot 	}
1756254Sroot 
1766254Sroot out:
1776254Sroot 	iput(ip);
1786254Sroot }
1796254Sroot 
1806254Sroot /*
1816254Sroot  * link system call
1826254Sroot  */
1836254Sroot link()
1846254Sroot {
1856254Sroot 	register struct inode *ip, *xp;
1866254Sroot 	register struct a {
1876254Sroot 		char	*target;
1886254Sroot 		char	*linkname;
1896254Sroot 	} *uap;
1906254Sroot 
1916254Sroot 	uap = (struct a *)u.u_ap;
1926254Sroot 	ip = namei(uchar, 0, 1);    /* well, this routine is doomed anyhow */
1936254Sroot 	if (ip == NULL)
1946254Sroot 		return;
1956254Sroot 	if ((ip->i_mode&IFMT)==IFDIR && !suser())
1966254Sroot 		goto out1;
1976254Sroot 	ip->i_nlink++;
1986254Sroot 	ip->i_flag |= ICHG;
1996254Sroot 	iupdat(ip, &time, &time, 1);
2007122Smckusick 	iunlock(ip);
2016254Sroot 	u.u_dirp = (caddr_t)uap->linkname;
2026254Sroot 	xp = namei(uchar, 1, 0);
2036254Sroot 	if (xp != NULL) {
2046254Sroot 		u.u_error = EEXIST;
2056254Sroot 		iput(xp);
2066254Sroot 		goto out;
2076254Sroot 	}
2086254Sroot 	if (u.u_error)
2096254Sroot 		goto out;
2106254Sroot 	if (u.u_pdir->i_dev != ip->i_dev) {
2116254Sroot 		iput(u.u_pdir);
2126254Sroot 		u.u_error = EXDEV;
2136254Sroot 		goto out;
2146254Sroot 	}
2156254Sroot 	wdir(ip);
2166254Sroot out:
2176254Sroot 	if (u.u_error) {
2186254Sroot 		ip->i_nlink--;
2196254Sroot 		ip->i_flag |= ICHG;
2206254Sroot 	}
2216254Sroot out1:
222*7142Smckusick 	irele(ip);
2236254Sroot }
2246254Sroot 
2256254Sroot /*
2266254Sroot  * symlink -- make a symbolic link
2276254Sroot  */
2286254Sroot symlink()
2296254Sroot {
2306254Sroot 	register struct a {
2316254Sroot 		char	*target;
2326254Sroot 		char	*linkname;
2336254Sroot 	} *uap;
2346254Sroot 	register struct inode *ip;
2356254Sroot 	register char *tp;
2366254Sroot 	register c, nc;
2376254Sroot 
2386254Sroot 	uap = (struct a *)u.u_ap;
2396254Sroot 	tp = uap->target;
2406254Sroot 	nc = 0;
2416254Sroot 	while (c = fubyte(tp)) {
2426254Sroot 		if (c < 0) {
2436254Sroot 			u.u_error = EFAULT;
2446254Sroot 			return;
2456254Sroot 		}
2466254Sroot 		tp++;
2476254Sroot 		nc++;
2486254Sroot 	}
2496254Sroot 	u.u_dirp = uap->linkname;
2506254Sroot 	ip = namei(uchar, 1, 0);
2516254Sroot 	if (ip) {
2526254Sroot 		iput(ip);
2536254Sroot 		u.u_error = EEXIST;
2546254Sroot 		return;
2556254Sroot 	}
2566254Sroot 	if (u.u_error)
2576254Sroot 		return;
2586254Sroot 	ip = maknode(IFLNK | 0777);
2596254Sroot 	if (ip == NULL)
2606254Sroot 		return;
2616254Sroot 	u.u_base = uap->target;
2626254Sroot 	u.u_count = nc;
2636254Sroot 	u.u_offset = 0;
2646254Sroot 	u.u_segflg = 0;
2656254Sroot 	writei(ip);
2666254Sroot 	iput(ip);
2676254Sroot }
2686254Sroot 
2696254Sroot /*
2706254Sroot  * Unlink system call.
2716254Sroot  * Hard to avoid races here, especially
2726254Sroot  * in unlinking directories.
2736254Sroot  */
2746254Sroot unlink()
2756254Sroot {
2766254Sroot 	register struct inode *ip, *pp;
2776254Sroot 	struct a {
2786254Sroot 		char	*fname;
2796254Sroot 	};
2806574Smckusic 	struct fs *fs;
2816574Smckusic 	struct buf *bp;
2826574Smckusic 	int lbn, bn, base;
283*7142Smckusick 	int unlinkingdot = 0;
2846254Sroot 
2856254Sroot 	pp = namei(uchar, 2, 0);
2866254Sroot 	if(pp == NULL)
2876254Sroot 		return;
2886254Sroot 	/*
2896254Sroot 	 * Check for unlink(".")
2906254Sroot 	 * to avoid hanging on the iget
2916254Sroot 	 */
2926254Sroot 	if (pp->i_number == u.u_dent.d_ino) {
2936254Sroot 		ip = pp;
2946254Sroot 		ip->i_count++;
295*7142Smckusick 		unlinkingdot++;
2966254Sroot 	} else
2976574Smckusic 		ip = iget(pp->i_dev, pp->i_fs, u.u_dent.d_ino);
2986254Sroot 	if(ip == NULL)
2996254Sroot 		goto out1;
3006254Sroot 	if((ip->i_mode&IFMT)==IFDIR && !suser())
3016254Sroot 		goto out;
3026254Sroot 	/*
3036254Sroot 	 * Don't unlink a mounted file.
3046254Sroot 	 */
3056254Sroot 	if (ip->i_dev != pp->i_dev) {
3066254Sroot 		u.u_error = EBUSY;
3076254Sroot 		goto out;
3086254Sroot 	}
3096254Sroot 	if (ip->i_flag&ITEXT)
3106254Sroot 		xrele(ip);	/* try once to free text */
3116254Sroot /*
3126254Sroot 	if ((ip->i_flag&ITEXT) && ip->i_nlink==1) {
3136254Sroot  		u.u_error = ETXTBSY;
3146254Sroot 		goto out;
3156254Sroot 	}
3166254Sroot */
3176574Smckusic 	if (u.u_count == 0) {
3186574Smckusic 		/*
3196574Smckusic 		 * first entry in block, so set d_ino to zero.
3206574Smckusic 		 */
3216574Smckusic 		u.u_base = (caddr_t)&u.u_dent;
3226574Smckusic 		u.u_count = DIRSIZ(&u.u_dent);
3236574Smckusic 		u.u_dent.d_ino = 0;
3246574Smckusic 		writei(pp);
3256574Smckusic 	} else {
3266574Smckusic 		/*
3276574Smckusic 		 * updating preceeding entry to skip over current entry.
3286574Smckusic 		 */
3296574Smckusic 		fs = pp->i_fs;
3306574Smckusic 		lbn = lblkno(fs, u.u_offset);
3316574Smckusic 		base = blkoff(fs, u.u_offset);
3326574Smckusic 		bn = fsbtodb(fs, bmap(pp, lbn, B_WRITE, base + u.u_count));
3336574Smckusic 		bp = bread(pp->i_dev, bn, blksize(fs, pp, lbn));
3346574Smckusic 		if (bp->b_flags & B_ERROR) {
3356574Smckusic 			brelse(bp);
3366574Smckusic 			goto out;
3376574Smckusic 		}
3386574Smckusic 		((struct direct *)(bp->b_un.b_addr + base))->d_reclen +=
3396574Smckusic 		    u.u_dent.d_reclen;
3406574Smckusic 		bwrite(bp);
3416574Smckusic 		pp->i_flag |= IUPD|ICHG;
3426574Smckusic 	}
3436254Sroot 	ip->i_nlink--;
3446254Sroot 	ip->i_flag |= ICHG;
3456254Sroot 
3466254Sroot out:
347*7142Smckusick 	if (unlinkingdot)
348*7142Smckusick 		irele(ip);
349*7142Smckusick 	else
350*7142Smckusick 		iput(ip);
3516254Sroot out1:
3526254Sroot 	iput(pp);
3536254Sroot }
3546254Sroot 
3556254Sroot /*
3566254Sroot  * Seek system call
3576254Sroot  */
3586254Sroot seek()
3596254Sroot {
3606254Sroot 	register struct file *fp;
3616254Sroot 	register struct a {
3626254Sroot 		int	fdes;
3636254Sroot 		off_t	off;
3646254Sroot 		int	sbase;
3656254Sroot 	} *uap;
3666254Sroot 
3676254Sroot 	uap = (struct a *)u.u_ap;
3686254Sroot 	fp = getf(uap->fdes);
3696254Sroot 	if (fp == NULL)
3706254Sroot 		return;
3716254Sroot 	if (fp->f_flag&FSOCKET) {
3726254Sroot 		u.u_error = ESPIPE;
3736254Sroot 		return;
3746254Sroot 	}
3756254Sroot 	if (uap->sbase == 1)
3766254Sroot 		uap->off += fp->f_offset;
3776254Sroot 	else if (uap->sbase == 2)
3786254Sroot 		uap->off += fp->f_inode->i_size;
3796254Sroot 	fp->f_offset = uap->off;
3806254Sroot 	u.u_r.r_off = uap->off;
3816254Sroot }
3826254Sroot 
3836254Sroot /*
3846254Sroot  * Access system call
3856254Sroot  */
3866254Sroot saccess()
3876254Sroot {
3886254Sroot 	register svuid, svgid;
3896254Sroot 	register struct inode *ip;
3906254Sroot 	register struct a {
3916254Sroot 		char	*fname;
3926254Sroot 		int	fmode;
3936254Sroot 	} *uap;
3946254Sroot 
3956254Sroot 	uap = (struct a *)u.u_ap;
3966254Sroot 	svuid = u.u_uid;
3976254Sroot 	svgid = u.u_gid;
3986254Sroot 	u.u_uid = u.u_ruid;
3996254Sroot 	u.u_gid = u.u_rgid;
4006254Sroot 	ip = namei(uchar, 0, 1);
4016254Sroot 	if (ip != NULL) {
4026254Sroot 		if (uap->fmode&(IREAD>>6))
4036254Sroot 			(void) access(ip, IREAD);
4046254Sroot 		if (uap->fmode&(IWRITE>>6))
4056254Sroot 			(void) access(ip, IWRITE);
4066254Sroot 		if (uap->fmode&(IEXEC>>6))
4076254Sroot 			(void) access(ip, IEXEC);
4086254Sroot 		iput(ip);
4096254Sroot 	}
4106254Sroot 	u.u_uid = svuid;
4116254Sroot 	u.u_gid = svgid;
4126254Sroot }
4136254Sroot 
4146254Sroot /*
41537Sbill  * the fstat system call.
41637Sbill  */
41737Sbill fstat()
41837Sbill {
41937Sbill 	register struct file *fp;
42037Sbill 	register struct a {
42137Sbill 		int	fdes;
42237Sbill 		struct stat *sb;
42337Sbill 	} *uap;
42437Sbill 
42537Sbill 	uap = (struct a *)u.u_ap;
42637Sbill 	fp = getf(uap->fdes);
4274828Swnj 	if (fp == NULL)
42837Sbill 		return;
4294828Swnj 	if (fp->f_flag & FSOCKET)
4304891Swnj 		u.u_error = sostat(fp->f_socket, uap->sb);
4314828Swnj 	else
4324828Swnj 		stat1(fp->f_inode, uap->sb);
43337Sbill }
43437Sbill 
43537Sbill /*
4366574Smckusic  * Stat system call.  This version follows links.
43737Sbill  */
43837Sbill stat()
43937Sbill {
44037Sbill 	register struct inode *ip;
44137Sbill 	register struct a {
44237Sbill 		char	*fname;
44337Sbill 		struct stat *sb;
44437Sbill 	} *uap;
44537Sbill 
44637Sbill 	uap = (struct a *)u.u_ap;
4476423Sroot 	ip = namei(uchar, 0, 1);
4484828Swnj 	if (ip == NULL)
44937Sbill 		return;
4503624Sroot 	stat1(ip, uap->sb);
45137Sbill 	iput(ip);
45237Sbill }
45337Sbill 
45437Sbill /*
4556574Smckusic  * Lstat system call.  This version does not follow links.
4565992Swnj  */
4575992Swnj lstat()
4585992Swnj {
4595992Swnj 	register struct inode *ip;
4605992Swnj 	register struct a {
4615992Swnj 		char	*fname;
4625992Swnj 		struct stat *sb;
4635992Swnj 	} *uap;
4645992Swnj 
4655992Swnj 	uap = (struct a *)u.u_ap;
4666423Sroot 	ip = namei(uchar, 0, 0);
4675992Swnj 	if (ip == NULL)
4685992Swnj 		return;
4696153Ssam 	stat1(ip, uap->sb);
4705992Swnj 	iput(ip);
4715992Swnj }
4725992Swnj 
4735992Swnj /*
47437Sbill  * The basic routine for fstat and stat:
47537Sbill  * get the inode and pass appropriate parts back.
47637Sbill  */
4773624Sroot stat1(ip, ub)
4784828Swnj 	register struct inode *ip;
4794828Swnj 	struct stat *ub;
48037Sbill {
48137Sbill 	struct stat ds;
48237Sbill 
4831204Sbill 	IUPDAT(ip, &time, &time, 0);
48437Sbill 	/*
4857023Smckusick 	 * Copy from inode table
48637Sbill 	 */
48737Sbill 	ds.st_dev = ip->i_dev;
48837Sbill 	ds.st_ino = ip->i_number;
48937Sbill 	ds.st_mode = ip->i_mode;
49037Sbill 	ds.st_nlink = ip->i_nlink;
49137Sbill 	ds.st_uid = ip->i_uid;
49237Sbill 	ds.st_gid = ip->i_gid;
4936574Smckusic 	ds.st_rdev = (dev_t)ip->i_rdev;
4943624Sroot 	ds.st_size = ip->i_size;
4956574Smckusic 	ds.st_atime = ip->i_atime;
4966574Smckusic 	ds.st_mtime = ip->i_mtime;
4976574Smckusic 	ds.st_ctime = ip->i_ctime;
4987023Smckusick 	ds.st_blksize = ip->i_fs->fs_bsize;
49937Sbill 	if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0)
50037Sbill 		u.u_error = EFAULT;
50137Sbill }
50237Sbill 
50337Sbill /*
5045992Swnj  * Return target name of a symbolic link
50537Sbill  */
5065992Swnj readlink()
5075992Swnj {
5085992Swnj 	register struct inode *ip;
5095992Swnj 	register struct a {
5105992Swnj 		char	*name;
5115992Swnj 		char	*buf;
5125992Swnj 		int	count;
5135992Swnj 	} *uap;
5145992Swnj 
5155992Swnj 	ip = namei(uchar, 0, 0);
5165992Swnj 	if (ip == NULL)
5175992Swnj 		return;
5185992Swnj 	if ((ip->i_mode&IFMT) != IFLNK) {
5195992Swnj 		u.u_error = ENXIO;
5205992Swnj 		goto out;
5215992Swnj 	}
5225992Swnj 	uap = (struct a *)u.u_ap;
5235992Swnj 	u.u_offset = 0;
5245992Swnj 	u.u_base = uap->buf;
5255992Swnj 	u.u_count = uap->count;
5265992Swnj 	u.u_segflg = 0;
5275992Swnj 	readi(ip);
5285992Swnj out:
5295992Swnj 	iput(ip);
5305992Swnj 	u.u_r.r_val1 = uap->count - u.u_count;
5315992Swnj }
5325992Swnj 
5336254Sroot chmod()
5345992Swnj {
5356254Sroot 	register struct inode *ip;
5365992Swnj 	register struct a {
5376254Sroot 		char	*fname;
5386254Sroot 		int	fmode;
5395992Swnj 	} *uap;
5405992Swnj 
5415992Swnj 	uap = (struct a *)u.u_ap;
5426254Sroot 	if ((ip = owner(1)) == NULL)
5435992Swnj 		return;
5446254Sroot 	ip->i_mode &= ~07777;
5456254Sroot 	if (u.u_uid)
5466254Sroot 		uap->fmode &= ~ISVTX;
5476254Sroot 	ip->i_mode |= uap->fmode&07777;
5486254Sroot 	ip->i_flag |= ICHG;
5496254Sroot 	if (ip->i_flag&ITEXT && (ip->i_mode&ISVTX)==0)
5506254Sroot 		xrele(ip);
5515992Swnj 	iput(ip);
5525992Swnj }
5535992Swnj 
5546254Sroot chown()
55537Sbill {
5566254Sroot 	register struct inode *ip;
55737Sbill 	register struct a {
5586254Sroot 		char	*fname;
5596254Sroot 		int	uid;
5606254Sroot 		int	gid;
56137Sbill 	} *uap;
56237Sbill 
56337Sbill 	uap = (struct a *)u.u_ap;
5646254Sroot 	if (!suser() || (ip = owner(0)) == NULL)
56537Sbill 		return;
5666254Sroot 	ip->i_uid = uap->uid;
5676254Sroot 	ip->i_gid = uap->gid;
5686254Sroot 	ip->i_flag |= ICHG;
5696254Sroot 	if (u.u_ruid != 0)
5706254Sroot 		ip->i_mode &= ~(ISUID|ISGID);
5716254Sroot 	iput(ip);
57237Sbill }
57337Sbill 
57437Sbill /*
5756254Sroot  * Set IUPD and IACC times on file.
5766254Sroot  * Can't set ICHG.
57737Sbill  */
5786254Sroot utime()
5794828Swnj {
58037Sbill 	register struct a {
5816254Sroot 		char	*fname;
5826254Sroot 		time_t	*tptr;
58337Sbill 	} *uap;
5846254Sroot 	register struct inode *ip;
5856254Sroot 	time_t tv[2];
58637Sbill 
58737Sbill 	uap = (struct a *)u.u_ap;
5886254Sroot 	if ((ip = owner(1)) == NULL)
58937Sbill 		return;
5906254Sroot 	if (copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof(tv))) {
5916254Sroot 		u.u_error = EFAULT;
5926254Sroot 	} else {
5936254Sroot 		ip->i_flag |= IACC|IUPD|ICHG;
5946254Sroot 		iupdat(ip, &tv[0], &tv[1], 0);
59537Sbill 	}
59637Sbill 	iput(ip);
59737Sbill }
59837Sbill 
5996254Sroot sync()
60037Sbill {
60137Sbill 
6025416Swnj 	update(0);
60337Sbill }
604