sys/sys3.c

07000 #include "../h/param.h" 07001 #include "../h/systm.h" 07002 #include "../h/mount.h" 07003 #include "../h/ino.h" 07004 #include "../h/reg.h" 07005 #include "../h/buf.h" 07006 #include "../h/filsys.h" 07007 #include "../h/dir.h" 07008 #include "../h/user.h" 07009 #include "../h/inode.h" 07010 #include "../h/file.h" 07011 #include "../h/conf.h" 07012 #include "../h/stat.h" 07013 07014 /* 07015 * the fstat system call. 07016 */ 07017 fstat() 07018 { 07019 register struct file *fp; 07020 register struct a { 07021 int fdes; 07022 struct stat *sb; 07023 } *uap; 07024 07025 uap = (struct a *)u.u_ap; 07026 fp = getf(uap->fdes); 07027 if(fp == NULL) 07028 return; 07029 stat1(fp->f_inode, uap->sb, fp->f_flag&FPIPE? fp->f_un.f_offset: 0); 07030 } 07031 07032 /* 07033 * the stat system call. 07034 */ 07035 stat() 07036 { 07037 register struct inode *ip; 07038 register struct a { 07039 char *fname; 07040 struct stat *sb; 07041 } *uap; 07042 07043 uap = (struct a *)u.u_ap; 07044 ip = namei(uchar, 0); 07045 if(ip == NULL) 07046 return; 07047 stat1(ip, uap->sb, (off_t)0); 07048 iput(ip); 07049 } 07050 07051 /* 07052 * The basic routine for fstat and stat: 07053 * get the inode and pass appropriate parts back. 07054 */ 07055 stat1(ip, ub, pipeadj) 07056 register struct inode *ip; 07057 struct stat *ub; 07058 off_t pipeadj; 07059 { 07060 register struct dinode *dp; 07061 register struct buf *bp; 07062 struct stat ds; 07063 07064 iupdat(ip, &time, &time); 07065 /* 07066 * first copy from inode table 07067 */ 07068 ds.st_dev = ip->i_dev; 07069 ds.st_ino = ip->i_number; 07070 ds.st_mode = ip->i_mode; 07071 ds.st_nlink = ip->i_nlink; 07072 ds.st_uid = ip->i_uid; 07073 ds.st_gid = ip->i_gid; 07074 ds.st_rdev = (dev_t)ip->i_un.i_rdev; 07075 ds.st_size = ip->i_size - pipeadj; 07076 /* 07077 * next the dates in the disk 07078 */ 07079 bp = bread(ip->i_dev, itod(ip->i_number)); 07080 dp = bp->b_un.b_dino; 07081 dp += itoo(ip->i_number); 07082 ds.st_atime = dp->di_atime; 07083 ds.st_mtime = dp->di_mtime; 07084 ds.st_ctime = dp->di_ctime; 07085 brelse(bp); 07086 if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0) 07087 u.u_error = EFAULT; 07088 } 07089 07090 /* 07091 * the dup system call. 07092 */ 07093 dup() 07094 { 07095 register struct file *fp; 07096 register struct a { 07097 int fdes; 07098 int fdes2; 07099 } *uap; 07100 register i, m; 07101 07102 uap = (struct a *)u.u_ap; 07103 m = uap->fdes & ~077; 07104 uap->fdes &= 077; 07105 fp = getf(uap->fdes); 07106 if(fp == NULL) 07107 return; 07108 if ((m&0100) == 0) { 07109 if ((i = ufalloc()) < 0) 07110 return; 07111 } else { 07112 i = uap->fdes2; 07113 if (i<0 || i>=NOFILE) { 07114 u.u_error = EBADF; 07115 return; 07116 } 07117 u.u_r.r_val1 = i; 07118 } 07119 if (i!=uap->fdes) { 07120 if (u.u_ofile[i]!=NULL) 07121 closef(u.u_ofile[i]); 07122 u.u_ofile[i] = fp; 07123 fp->f_count++; 07124 } 07125 } 07126 07127 /* 07128 * the mount system call. 07129 */ 07130 smount() 07131 { 07132 dev_t dev; 07133 register struct inode *ip; 07134 register struct mount *mp; 07135 struct mount *smp; 07136 register struct filsys *fp; 07137 struct buf *bp; 07138 register struct a { 07139 char *fspec; 07140 char *freg; 07141 int ronly; 07142 } *uap; 07143 07144 uap = (struct a *)u.u_ap; 07145 dev = getmdev(); 07146 if(u.u_error) 07147 return; 07148 u.u_dirp = (caddr_t)uap->freg; 07149 ip = namei(uchar, 0); 07150 if(ip == NULL) 07151 return; 07152 if(ip->i_count!=1 || (ip->i_mode&(IFBLK&IFCHR))!=0) 07153 goto out; 07154 smp = NULL; 07155 for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) { 07156 if(mp->m_bufp != NULL) { 07157 if(dev == mp->m_dev) 07158 goto out; 07159 } else 07160 if(smp == NULL) 07161 smp = mp; 07162 } 07163 mp = smp; 07164 if(mp == NULL) 07165 goto out; 07166 (*bdevsw[major(dev)].d_open)(dev, !uap->ronly); 07167 if(u.u_error) 07168 goto out; 07169 bp = bread(dev, SUPERB); 07170 if(u.u_error) { 07171 brelse(bp); 07172 goto out1; 07173 } 07174 mp->m_inodp = ip; 07175 mp->m_dev = dev; 07176 mp->m_bufp = geteblk(); 07177 bcopy((caddr_t)bp->b_un.b_addr, mp->m_bufp->b_un.b_addr, BSIZE); 07178 fp = mp->m_bufp->b_un.b_filsys; 07179 fp->s_ilock = 0; 07180 fp->s_flock = 0; 07181 fp->s_ronly = uap->ronly & 1; 07182 brelse(bp); 07183 ip->i_flag |= IMOUNT; 07184 prele(ip); 07185 return; 07186 07187 out: 07188 u.u_error = EBUSY; 07189 out1: 07190 iput(ip); 07191 } 07192 07193 /* 07194 * the umount system call. 07195 */ 07196 sumount() 07197 { 07198 dev_t dev; 07199 register struct inode *ip; 07200 register struct mount *mp; 07201 struct buf *bp; 07202 register struct a { 07203 char *fspec; 07204 }; 07205 07206 dev = getmdev(); 07207 if(u.u_error) 07208 return; 07209 xumount(dev); /* remove unused sticky files from text table */ 07210 update(); 07211 for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) 07212 if(mp->m_bufp != NULL && dev == mp->m_dev) 07213 goto found; 07214 u.u_error = EINVAL; 07215 return; 07216 07217 found: 07218 for(ip = &inode[0]; ip < &inode[NINODE]; ip++) 07219 if(ip->i_number != 0 && dev == ip->i_dev) { 07220 u.u_error = EBUSY; 07221 return; 07222 } 07223 (*bdevsw[major(dev)].d_close)(dev, 0); 07224 ip = mp->m_inodp; 07225 ip->i_flag &= ~IMOUNT; 07226 plock(ip); 07227 iput(ip); 07228 bp = mp->m_bufp; 07229 mp->m_bufp = NULL; 07230 brelse(bp); 07231 } 07232 07233 /* 07234 * Common code for mount and umount. 07235 * Check that the user's argument is a reasonable 07236 * thing on which to mount, and return the device number if so. 07237 */ 07238 dev_t 07239 getmdev() 07240 { 07241 dev_t dev; 07242 register struct inode *ip; 07243 07244 ip = namei(uchar, 0); 07245 if(ip == NULL) 07246 return(NODEV); 07247 if((ip->i_mode&IFMT) != IFBLK) 07248 u.u_error = ENOTBLK; 07249 dev = (dev_t)ip->i_un.i_rdev; 07250 if(major(dev) >= nblkdev) 07251 u.u_error = ENXIO; 07252 iput(ip); 07253 return(dev); 07254 } 07255 07256 07257 07258 07259 07260 07261 07262 07263 07264 07265 07266 07267 07268 07269 07270 07271 07272 07273 07274 07275 07276 07277 07278 07279 07280 07281 07282 07283 07284 07285 07286 07287 07288 07289 07290 07291 07292 07293 07294 07295 07296 07297 07298 07299