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: /* ---------------------------       */