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