rdwri.c

6200 # 6201 /* 6202 */ 6203 6204 #include "../param.h" 6205 #include "../inode.h" 6206 #include "../user.h" 6207 #include "../buf.h" 6208 #include "../conf.h" 6209 #include "../systm.h" 6210 6211 /* 6212 * Read the file corresponding to 6213 * the inode pointed at by the argument. 6214 * The actual read arguments are found 6215 * in the variables: 6216 * u_base core address for destination 6217 * u_offset byte offset in file 6218 * u_count number of bytes to read 6219 * u_segflg read to kernel/user 6220 */ 6221 readi(aip) 6222 struct inode *aip; 6223 { 6224 int *bp; 6225 int lbn, bn, on; 6226 register dn, n; 6227 register struct inode *ip; 6228 6229 ip = aip; 6230 if(u.u_count == 0) 6231 return; 6232 ip->i_flag =| IACC; 6233 if((ip->i_mode&IFMT) == IFCHR) { 6234 (*cdevsw[ip->i_addr[0].d_major].d_read)(ip->i_addr[0]); 6235 return; 6236 } 6237 6238 do { 6239 lbn = bn = lshift(u.u_offset, -9); 6240 on = u.u_offset[1] & 0777; 6241 n = min(512-on, u.u_count); 6242 if((ip->i_mode&IFMT) != IFBLK) { 6243 dn = dpcmp(ip->i_size0&0377, ip->i_size1, 6244 u.u_offset[0], u.u_offset[1]); 6245 if(dn <= 0) 6246 return; 6247 n = min(n, dn); 6248 if ((bn = bmap(ip, lbn)) == 0) 6249 return; 6250 dn = ip->i_dev; 6251 } else { 6252 dn = ip->i_addr[0]; 6253 rablock = bn+1; 6254 } 6255 if (ip->i_lastr+1 == lbn) 6256 bp = breada(dn, bn, rablock); 6257 else 6258 bp = bread(dn, bn); 6259 ip->i_lastr = lbn; 6260 iomove(bp, on, n, B_READ); 6261 brelse(bp); 6262 } while(u.u_error==0 && u.u_count!=0); 6263 } 6264 /* ------------------------ */ 6265 6266 /* 6267 * Write the file corresponding to 6268 * the inode pointed at by the argument. 6269 * The actual write arguments are found 6270 * in the variables: 6271 * u_base core address for source 6272 * u_offset byte offset in file 6273 * u_count number of bytes to write 6274 * u_segflg write to kernel/user 6275 */ 6276 writei(aip) 6277 struct inode *aip; 6278 { 6279 int *bp; 6280 int n, on; 6281 register dn, bn; 6282 register struct inode *ip; 6283 6284 ip = aip; 6285 ip->i_flag =| IACC|IUPD; 6286 if((ip->i_mode&IFMT) == IFCHR) { 6287 (*cdevsw[ip->i_addr[0].d_major].d_write)(ip->i_addr[0]); 6288 return; 6289 } 6290 if (u.u_count == 0) 6291 return; 6292 6293 do { 6294 bn = lshift(u.u_offset, -9); 6295 on = u.u_offset[1] & 0777; 6296 n = min(512-on, u.u_count); 6297 if((ip->i_mode&IFMT) != IFBLK) { 6298 if ((bn = bmap(ip, bn)) == 0) 6299 return; 6300 dn = ip->i_dev; 6301 } else 6302 dn = ip->i_addr[0]; 6303 if(n == 512) 6304 bp = getblk(dn, bn); else 6305 bp = bread(dn, bn); 6306 iomove(bp, on, n, B_WRITE); 6307 if(u.u_error != 0) 6308 brelse(bp); else 6309 if ((u.u_offset[1]&0777)==0) 6310 bawrite(bp); else 6311 bdwrite(bp); 6312 if(dpcmp(ip->i_size0&0377, ip->i_size1, 6313 u.u_offset[0], u.u_offset[1]) < 0 && 6314 (ip->i_mode&(IFBLK&IFCHR)) == 0) { 6315 ip->i_size0 = u.u_offset[0]; 6316 ip->i_size1 = u.u_offset[1]; 6317 } 6318 ip->i_flag =| IUPD; 6319 } while(u.u_error==0 && u.u_count!=0); 6320 } 6321 /* ------------------------ */ 6322 6323 /* Return the logical maximum 6324 * of the 2 arguments. 6325 */ 6326 max(a, b) 6327 char *a, *b; 6328 { 6329 6330 if(a > b) 6331 return(a); 6332 return(b); 6333 } 6334 /* ------------------------ */ 6335 6336 /* Return the logical minimum 6337 * of the 2 arguments. 6338 */ 6339 min(a, b) 6340 char *a, *b; 6341 { 6342 6343 if(a < b) 6344 return(a); 6345 return(b); 6346 } 6347 /* ------------------------ */ 6348 6349 /* 6350 * Move 'an' bytes at byte location 6351 * &bp->b_addr[o] to/from (flag) the 6352 * user/kernel (u.segflg) area starting at u.base. 6353 * Update all the arguments by the number 6354 * of bytes moved. 6355 * 6356 * There are 2 algorithms, 6357 * if source address, dest address and count 6358 * are all even in a user copy, 6359 * then the machine language copyin/copyout 6360 * is called. 6361 * If not, its done byte-by-byte with 6362 * cpass and passc. 6363 */ 6364 iomove(bp, o, an, flag) 6365 struct buf *bp; 6366 { 6367 register char *cp; 6368 register int n, t; 6369 6370 n = an; 6371 cp = bp->b_addr + o; 6372 if(u.u_segflg==0 && ((n | cp | u.u_base)&01)==0) { 6373 if (flag==B_WRITE) 6374 cp = copyin(u.u_base, cp, n); 6375 else 6376 cp = copyout(cp, u.u_base, n); 6377 if (cp) { 6378 u.u_error = EFAULT; 6379 return; 6380 } 6381 u.u_base =+ n; 6382 dpadd(u.u_offset, n); 6383 u.u_count =- n; 6384 return; 6385 } 6386 if (flag==B_WRITE) { 6387 while(n--) { 6388 if ((t = cpass()) < 0) 6389 return; 6390 *cp++ = t; 6391 } 6392 } else 6393 while (n--) 6394 if(passc(*cp++) < 0) 6395 return; 6396 } 6397 /* ------------------------ */ 6398 6399