sys3.c

6000 # 6001 #include "../param.h" 6002 #include "../systm.h" 6003 #include "../reg.h" 6004 #include "../buf.h" 6005 #include "../filsys.h" 6006 #include "../user.h" 6007 #include "../inode.h" 6008 #include "../file.h" 6009 #include "../conf.h" 6010 6011 /* 6012 * the fstat system call. 6013 */ 6014 fstat() 6015 { 6016 register *fp; 6017 6018 fp = getf(u.u_ar0[R0]); 6019 if(fp == NULL) 6020 return; 6021 stat1(fp->f_inode, u.u_arg[0]); 6022 } 6023 /* ------------------------ */ 6024 6025 /* 6026 * the stat system call. 6027 */ 6028 stat() 6029 { 6030 register ip; 6031 extern uchar; 6032 6033 ip = namei(&uchar, 0); 6034 if(ip == NULL) 6035 return; 6036 stat1(ip, u.u_arg[1]); 6037 iput(ip); 6038 } 6039 /* ------------------------ */ 6040 6041 /* 6042 * The basic routine for fstat and stat: 6043 * get the inode and pass appropriate parts back. 6044 */ 6045 stat1(ip, ub) 6046 int *ip; 6047 { 6048 register i, *bp, *cp; 6049 6050 iupdat(ip, time); 6051 bp = bread(ip->i_dev, ldiv(ip->i_number+31, 16)); 6052 cp = bp->b_addr + 32*lrem(ip->i_number+31, 16) + 24; 6053 ip = &(ip->i_dev); 6054 for(i=0; i<14; i++) { 6055 suword(ub, *ip++); 6056 ub =+ 2; 6057 } 6058 for(i=0; i<4; i++) { 6059 suword(ub, *cp++); 6060 ub =+ 2; 6061 } 6062 brelse(bp); 6063 } 6064 /* ------------------------ */ 6065 6066 /* 6067 * the dup system call. 6068 */ 6069 dup() 6070 { 6071 register i, *fp; 6072 6073 fp = getf(u.u_ar0[R0]); 6074 if(fp == NULL) 6075 return; 6076 if ((i = ufalloc()) < 0) 6077 return; 6078 u.u_ofile[i] = fp; 6079 fp->f_count++; 6080 } 6081 /* ------------------------ */ 6082 6083 /* 6084 * the mount system call. 6085 */ 6086 smount() 6087 { 6088 int d; 6089 register *ip; 6090 register struct mount *mp, *smp; 6091 extern uchar; 6092 6093 d = getmdev(); 6094 if(u.u_error) 6095 return; 6096 u.u_dirp = u.u_arg[1]; 6097 ip = namei(&uchar, 0); 6098 if(ip == NULL) 6099 return; 6100 if(ip->i_count!=1 || (ip->i_mode&(IFBLK&IFCHR))!=0) 6101 goto out; 6102 smp = NULL; 6103 for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) { 6104 if(mp->m_bufp != NULL) { 6105 if(d == mp->m_dev) 6106 goto out; 6107 } else 6108 if(smp == NULL) 6109 smp = mp; 6110 } 6111 if(smp == NULL) 6112 goto out; 6113 (*bdevsw[d.d_major].d_open)(d, !u.u_arg[2]); 6114 if(u.u_error) 6115 goto out; 6116 mp = bread(d, 1); 6117 if(u.u_error) { 6118 brelse(mp); 6119 goto out1; 6120 } 6121 smp->m_inodp = ip; 6122 smp->m_dev = d; 6123 smp->m_bufp = getblk(NODEV); 6124 bcopy(mp->b_addr, smp->m_bufp->b_addr, 256); 6125 smp = smp->m_bufp->b_addr; 6126 smp->s_ilock = 0; 6127 smp->s_flock = 0; 6128 smp->s_ronly = u.u_arg[2] & 1; 6129 brelse(mp); 6130 ip->i_flag =| IMOUNT; 6131 prele(ip); 6132 return; 6133 6134 out: 6135 u.u_error = EBUSY; 6136 out1: 6137 iput(ip); 6138 } 6139 /* ------------------------ */ 6140 6141 /* 6142 * the umount system call. 6143 */ 6144 sumount() 6145 { 6146 int d; 6147 register struct inode *ip; 6148 register struct mount *mp; 6149 6150 update(); 6151 d = getmdev(); 6152 if(u.u_error) 6153 return; 6154 for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) 6155 if(mp->m_bufp!=NULL && d==mp->m_dev) 6156 goto found; 6157 u.u_error = EINVAL; 6158 return; 6159 6160 found: 6161 for(ip = &inode[0]; ip < &inode[NINODE]; ip++) 6162 if(ip->i_number!=0 && d==ip->i_dev) { 6163 u.u_error = EBUSY; 6164 return; 6165 } 6166 (*bdevsw[d.d_major].d_close)(d, 0); 6167 ip = mp->m_inodp; 6168 ip->i_flag =& ~IMOUNT; 6169 iput(ip); 6170 ip = mp->m_bufp; 6171 mp->m_bufp = NULL; 6172 brelse(ip); 6173 } 6174 /* ------------------------ */ 6175 6176 /* 6177 * Common code for mount and umount. 6178 * Check that the user's argument is a reasonable 6179 * thing on which to mount, and return the device number if so. 6180 */ 6181 getmdev() 6182 { 6183 register d, *ip; 6184 extern uchar; 6185 6186 ip = namei(&uchar, 0); 6187 if(ip == NULL) 6188 return; 6189 if((ip->i_mode&IFMT) != IFBLK) 6190 u.u_error = ENOTBLK; 6191 d = ip->i_addr[0]; 6192 if(ip->i_addr[0].d_major >= nblkdev) 6193 u.u_error = ENXIO; 6194 iput(ip); 6195 return(d); 6196 } 6197 /* ------------------------ */ 6198 6199