1*1204Sbill /* vfs_syscalls.c 3.5 10/03/80 */ 237Sbill 337Sbill #include "../h/param.h" 437Sbill #include "../h/systm.h" 537Sbill #include "../h/mount.h" 637Sbill #include "../h/ino.h" 737Sbill #include "../h/reg.h" 837Sbill #include "../h/buf.h" 937Sbill #include "../h/filsys.h" 1037Sbill #include "../h/dir.h" 1137Sbill #include "../h/user.h" 1237Sbill #include "../h/inode.h" 1337Sbill #include "../h/file.h" 1437Sbill #include "../h/conf.h" 1537Sbill #include "../h/stat.h" 1694Sbill #include "../h/inline.h" 1737Sbill 1837Sbill /* 1937Sbill * the fstat system call. 2037Sbill */ 2137Sbill fstat() 2237Sbill { 2337Sbill register struct file *fp; 2437Sbill register struct a { 2537Sbill int fdes; 2637Sbill struct stat *sb; 2737Sbill } *uap; 2837Sbill 2937Sbill uap = (struct a *)u.u_ap; 3037Sbill fp = getf(uap->fdes); 3137Sbill if(fp == NULL) 3237Sbill return; 3337Sbill stat1(fp->f_inode, uap->sb, fp->f_flag&FPIPE? fp->f_un.f_offset: 0); 3437Sbill } 3537Sbill 3637Sbill /* 3737Sbill * the stat system call. 3837Sbill */ 3937Sbill stat() 4037Sbill { 4137Sbill register struct inode *ip; 4237Sbill register struct a { 4337Sbill char *fname; 4437Sbill struct stat *sb; 4537Sbill } *uap; 4637Sbill 4737Sbill uap = (struct a *)u.u_ap; 4837Sbill ip = namei(uchar, 0); 4937Sbill if(ip == NULL) 5037Sbill return; 5137Sbill stat1(ip, uap->sb, (off_t)0); 5237Sbill iput(ip); 5337Sbill } 5437Sbill 5537Sbill /* 5637Sbill * The basic routine for fstat and stat: 5737Sbill * get the inode and pass appropriate parts back. 5837Sbill */ 5937Sbill stat1(ip, ub, pipeadj) 6037Sbill register struct inode *ip; 6137Sbill struct stat *ub; 6237Sbill off_t pipeadj; 6337Sbill { 6437Sbill register struct dinode *dp; 6537Sbill register struct buf *bp; 6637Sbill struct stat ds; 6737Sbill 68*1204Sbill IUPDAT(ip, &time, &time, 0); 6937Sbill /* 7037Sbill * first copy from inode table 7137Sbill */ 7237Sbill ds.st_dev = ip->i_dev; 7337Sbill ds.st_ino = ip->i_number; 7437Sbill ds.st_mode = ip->i_mode; 7537Sbill ds.st_nlink = ip->i_nlink; 7637Sbill ds.st_uid = ip->i_uid; 7737Sbill ds.st_gid = ip->i_gid; 7837Sbill ds.st_rdev = (dev_t)ip->i_un.i_rdev; 7937Sbill ds.st_size = ip->i_size - pipeadj; 8037Sbill /* 8137Sbill * next the dates in the disk 8237Sbill */ 8337Sbill bp = bread(ip->i_dev, itod(ip->i_number)); 8437Sbill dp = bp->b_un.b_dino; 8537Sbill dp += itoo(ip->i_number); 8637Sbill ds.st_atime = dp->di_atime; 8737Sbill ds.st_mtime = dp->di_mtime; 8837Sbill ds.st_ctime = dp->di_ctime; 8937Sbill brelse(bp); 9037Sbill if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0) 9137Sbill u.u_error = EFAULT; 9237Sbill } 9337Sbill 9437Sbill /* 9537Sbill * the dup system call. 9637Sbill */ 9737Sbill dup() 9837Sbill { 9937Sbill register struct file *fp; 10037Sbill register struct a { 10137Sbill int fdes; 10237Sbill int fdes2; 10337Sbill } *uap; 10437Sbill register i, m; 10537Sbill 10637Sbill uap = (struct a *)u.u_ap; 10737Sbill m = uap->fdes & ~077; 10837Sbill uap->fdes &= 077; 10937Sbill fp = getf(uap->fdes); 11037Sbill if(fp == NULL) 11137Sbill return; 11237Sbill if ((m&0100) == 0) { 11337Sbill if ((i = ufalloc()) < 0) 11437Sbill return; 11537Sbill } else { 11637Sbill i = uap->fdes2; 11737Sbill if (i<0 || i>=NOFILE) { 11837Sbill u.u_error = EBADF; 11937Sbill return; 12037Sbill } 12137Sbill if (u.u_vrpages[i]) { 12237Sbill u.u_error = ETXTBSY; 12337Sbill return; 12437Sbill } 12537Sbill u.u_r.r_val1 = i; 12637Sbill } 12737Sbill if (i!=uap->fdes) { 12837Sbill if (u.u_ofile[i]!=NULL) 12937Sbill closef(u.u_ofile[i]); 13037Sbill u.u_ofile[i] = fp; 13137Sbill fp->f_count++; 13237Sbill } 13337Sbill } 13437Sbill 13537Sbill /* 13637Sbill * the mount system call. 13737Sbill */ 13837Sbill smount() 13937Sbill { 14037Sbill dev_t dev; 14137Sbill register struct inode *ip; 14237Sbill register struct mount *mp; 14337Sbill struct mount *smp; 14437Sbill register struct filsys *fp; 14537Sbill struct buf *bp; 14637Sbill register struct a { 14737Sbill char *fspec; 14837Sbill char *freg; 14937Sbill int ronly; 15037Sbill } *uap; 15137Sbill 15237Sbill uap = (struct a *)u.u_ap; 15337Sbill dev = getmdev(); 15437Sbill if(u.u_error) 15537Sbill return; 15637Sbill u.u_dirp = (caddr_t)uap->freg; 15737Sbill ip = namei(uchar, 0); 15837Sbill if(ip == NULL) 15937Sbill return; 16037Sbill if(ip->i_count!=1 || (ip->i_mode&(IFBLK&IFCHR))!=0) 16137Sbill goto out; 16237Sbill smp = NULL; 16337Sbill for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) { 16437Sbill if(mp->m_bufp != NULL) { 16537Sbill if(dev == mp->m_dev) 16637Sbill goto out; 16737Sbill } else 16837Sbill if(smp == NULL) 16937Sbill smp = mp; 17037Sbill } 17137Sbill mp = smp; 17237Sbill if(mp == NULL) 17337Sbill goto out; 17437Sbill (*bdevsw[major(dev)].d_open)(dev, !uap->ronly); 17537Sbill if(u.u_error) 17637Sbill goto out; 17737Sbill bp = bread(dev, SUPERB); 17837Sbill if(u.u_error) { 17937Sbill brelse(bp); 18037Sbill goto out1; 18137Sbill } 18237Sbill mp->m_inodp = ip; 18337Sbill mp->m_dev = dev; 18437Sbill mp->m_bufp = geteblk(); 18537Sbill bcopy((caddr_t)bp->b_un.b_addr, mp->m_bufp->b_un.b_addr, BSIZE); 18637Sbill fp = mp->m_bufp->b_un.b_filsys; 18737Sbill fp->s_ilock = 0; 18837Sbill fp->s_flock = 0; 18937Sbill fp->s_ronly = uap->ronly & 1; 19037Sbill fp->s_nbehind = 0; 19137Sbill fp->s_lasti = 1; 19237Sbill brelse(bp); 19337Sbill ip->i_flag |= IMOUNT; 19437Sbill prele(ip); 19537Sbill return; 19637Sbill 19737Sbill out: 19837Sbill u.u_error = EBUSY; 19937Sbill out1: 20037Sbill iput(ip); 20137Sbill } 20237Sbill 20337Sbill /* 20437Sbill * the umount system call. 20537Sbill */ 20637Sbill sumount() 20737Sbill { 20837Sbill dev_t dev; 20937Sbill register struct inode *ip; 21037Sbill register struct mount *mp; 21137Sbill struct buf *bp; 21237Sbill register struct a { 21337Sbill char *fspec; 21437Sbill }; 21537Sbill 21637Sbill dev = getmdev(); 21737Sbill if(u.u_error) 21837Sbill return; 21937Sbill xumount(dev); /* remove unused sticky files from text table */ 22037Sbill update(); 22137Sbill for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) 22237Sbill if(mp->m_bufp != NULL && dev == mp->m_dev) 22337Sbill goto found; 22437Sbill u.u_error = EINVAL; 22537Sbill return; 22637Sbill 22737Sbill found: 22837Sbill for(ip = &inode[0]; ip < &inode[NINODE]; ip++) 22937Sbill if(ip->i_number != 0 && dev == ip->i_dev) { 23037Sbill u.u_error = EBUSY; 23137Sbill return; 23237Sbill } 233349Sbill mpurge(mp - &mount[0]); 23437Sbill (*bdevsw[major(dev)].d_close)(dev, 0); 23537Sbill ip = mp->m_inodp; 23637Sbill ip->i_flag &= ~IMOUNT; 23737Sbill plock(ip); 23837Sbill iput(ip); 23937Sbill bp = mp->m_bufp; 24037Sbill mp->m_bufp = NULL; 24137Sbill brelse(bp); 24237Sbill } 24337Sbill 24437Sbill /* 24537Sbill * Common code for mount and umount. 24637Sbill * Check that the user's argument is a reasonable 24737Sbill * thing on which to mount, and return the device number if so. 24837Sbill */ 24937Sbill dev_t 25037Sbill getmdev() 25137Sbill { 25237Sbill dev_t dev; 25337Sbill register struct inode *ip; 25437Sbill 25537Sbill #ifdef UCB 25637Sbill if (!suser()) 25737Sbill return(NODEV); 25837Sbill #endif 25937Sbill ip = namei(uchar, 0); 26037Sbill if(ip == NULL) 26137Sbill return(NODEV); 26237Sbill if((ip->i_mode&IFMT) != IFBLK) 26337Sbill u.u_error = ENOTBLK; 26437Sbill dev = (dev_t)ip->i_un.i_rdev; 26537Sbill if(major(dev) >= nblkdev) 26637Sbill u.u_error = ENXIO; 26737Sbill iput(ip); 26837Sbill return(dev); 26937Sbill } 270