1: /*
   2:  *	SCCS id	@(#)rdwri.c	2.1 (Berkeley)	8/5/83
   3:  */
   4: 
   5: #include "param.h"
   6: #include <sys/systm.h>
   7: #include <sys/inode.h>
   8: #include <sys/dir.h>
   9: #include <sys/user.h>
  10: #include <sys/buf.h>
  11: #include <sys/conf.h>
  12: 
  13: /*
  14:  * Read the file corresponding to
  15:  * the inode pointed at by the argument.
  16:  * The actual read arguments are found
  17:  * in the variables:
  18:  *	u_base		core address for destination
  19:  *	u_offset	byte offset in file
  20:  *	u_count		number of bytes to read
  21:  *	u_segflg	read to kernel/user/user I
  22:  */
  23: readi(ip)
  24: register struct inode *ip;
  25: {
  26:     struct buf *bp;
  27:     dev_t dev;
  28:     daddr_t lbn, bn;
  29:     off_t diff;
  30:     register on, n;
  31:     int type;
  32: 
  33:     if(u.u_count == 0)
  34:         return;
  35:     if(u.u_offset < 0) {
  36:         u.u_error = EINVAL;
  37:         return;
  38:     }
  39:     ip->i_flag |= IACC;
  40:     dev = (dev_t)ip->i_un.i_rdev;
  41:     type = ip->i_mode&IFMT;
  42: #ifdef  MPX_FILS
  43:     if (type==IFCHR || type==IFMPC)
  44: #else
  45:     if (type==IFCHR)
  46: #endif
  47:         return((*cdevsw[major(dev)].d_read)(dev));
  48: 
  49:     do {
  50:         lbn = bn = u.u_offset >> BSHIFT;
  51:         on = u.u_offset & BMASK;
  52:         n = MIN((unsigned)(BSIZE-on), u.u_count);
  53: #ifdef  MPX_FILS
  54:         if (type!=IFBLK && type!=IFMPB)
  55: #else
  56:         if (type!=IFBLK)
  57: #endif
  58:             {
  59:             diff = ip->i_size - u.u_offset;
  60:             if(diff <= 0)
  61:                 return;
  62:             if(diff < n)
  63:                 n = diff;
  64:             bn = bmap(ip, bn, B_READ);
  65:             if(u.u_error)
  66:                 return;
  67:             dev = ip->i_dev;
  68:         } else
  69:             rablock = bn+1;
  70:         if ((long)bn<0) {
  71:             bp = geteblk();
  72:             clrbuf(bp);
  73:         } else if (ip->i_un.i_lastr+1==lbn)
  74:             bp = breada(dev, bn, rablock);
  75:         else
  76:             bp = bread(dev, bn);
  77:         ip->i_un.i_lastr = lbn;
  78:         n = MIN((unsigned)n, BSIZE-bp->b_resid);
  79:         if (n!=0) {
  80:             iomove(mapin(bp)+on, n, B_READ);
  81:             mapout(bp);
  82:         }
  83:         if (n+on==BSIZE || u.u_offset==ip->i_size) {
  84:             if (ip->i_flag & IPIPE)
  85:                 bp->b_flags &= ~B_DELWRI;   /* cancel i/o */
  86:             bp->b_flags |= B_AGE;
  87:         }
  88:         brelse(bp);
  89:     } while(u.u_error==0 && u.u_count!=0 && n>0);
  90: }
  91: 
  92: /*
  93:  * Write the file corresponding to
  94:  * the inode pointed at by the argument.
  95:  * The actual write arguments are found
  96:  * in the variables:
  97:  *	u_base		core address for source
  98:  *	u_offset	byte offset in file
  99:  *	u_count		number of bytes to write
 100:  *	u_segflg	write to kernel/user/user I
 101:  */
 102: writei(ip)
 103: register struct inode *ip;
 104: {
 105:     struct buf *bp;
 106:     dev_t dev;
 107:     daddr_t bn;
 108:     register n, on;
 109:     register type;
 110: #ifdef  UCB_FSFIX
 111:     struct  direct  *dp;
 112: #endif
 113: 
 114: #ifndef INSECURE
 115:     /*
 116: 	 * clear set-uid/gid on any write
 117: 	 */
 118:     ip->i_mode &= ~(ISUID|ISGID);
 119: #endif
 120:     if(u.u_offset < 0) {
 121:         u.u_error = EINVAL;
 122:         return;
 123:     }
 124:     dev = (dev_t)ip->i_un.i_rdev;
 125:     type = ip->i_mode&IFMT;
 126: #ifdef  MPX_FILS
 127:     if (type==IFCHR || type==IFMPC)
 128: #else
 129:     if (type==IFCHR)
 130: #endif
 131:         {
 132:         ip->i_flag |= IUPD|ICHG;
 133:         (*cdevsw[major(dev)].d_write)(dev);
 134:         return;
 135:     }
 136:     if (u.u_count == 0)
 137:         return;
 138:     do {
 139:         bn = u.u_offset >> BSHIFT;
 140:         on = u.u_offset & BMASK;
 141:         n = MIN((unsigned)(BSIZE-on), u.u_count);
 142: #ifdef  MPX_FILS
 143:         if (type!=IFBLK && type!=IFMPB)
 144: #else
 145:         if (type!=IFBLK)
 146: #endif
 147:             {
 148: #ifdef UCB_QUOTAS
 149:             if ((bn = bmap(ip, bn, B_WRITE)) == 0)
 150:                 return;
 151: #else
 152:             bn = bmap(ip, bn, B_WRITE);
 153: #endif
 154:             if (bn < 0)
 155:                 return;
 156:             dev = ip->i_dev;
 157:         }
 158:         if (n == BSIZE)
 159:             bp = getblk(dev, bn);
 160:         else {
 161:             bp = bread(dev, bn);
 162:             /*
 163: 			 * Tape drivers don't clear buffers on end-of-tape
 164: 			 * any longer (clrbuf can't be called from interrupt).
 165: 			 */
 166:             if (bp->b_resid == BSIZE)
 167:                 clrbuf(bp);
 168:         }
 169: #ifdef  UCB_FSFIX
 170:         iomove((dp = (struct direct *)((unsigned)mapin(bp)+on)), n, B_WRITE);
 171: #else
 172:         iomove(mapin(bp)+on, n, B_WRITE);
 173:         mapout(bp);
 174: #endif
 175:         if(u.u_error != 0) {
 176: #ifdef  UCB_FSFIX
 177:             mapout(bp);
 178: #endif
 179:             brelse(bp);
 180:         } else {
 181: #ifdef  UCB_FSFIX
 182:             if ((ip->i_mode&IFMT) == IFDIR && (dp->d_ino == 0)) {
 183:                 mapout(bp);
 184:                 /*
 185: 				 * Writing to clear a directory entry.
 186: 				 * Must insure the write occurs before
 187: 				 * the inode is freed, or may end up
 188: 				 * pointing at a new (different) file
 189: 				 * if inode is quickly allocated again
 190: 				 * and system crashes.
 191: 				 */
 192:                 bwrite(bp);
 193:             } else {
 194:                 mapout(bp);
 195:                 if (((u.u_offset & BMASK) == 0)
 196:                    && (ip->i_flag & IPIPE) == 0) {
 197:                     bp->b_flags |= B_AGE;
 198:                     bawrite(bp);
 199:                 } else
 200:                     bdwrite(bp);
 201:             }
 202: #else   UCB_FSFIX
 203: 
 204:             if (((u.u_offset & BMASK) == 0)
 205:                && (ip->i_flag & IPIPE) == 0)
 206:                 bp->b_flags |= B_AGE;
 207:             bdwrite(bp);
 208: #endif	UCB_FSFIX
 209:         }
 210: #ifndef UCB_SYMLINKS
 211:         if (u.u_offset > ip->i_size && (type == IFDIR || type == IFREG))
 212: #else
 213:         if (u.u_offset > ip->i_size && (type == IFDIR || type == IFREG || type == IFLNK))
 214: #endif
 215:             ip->i_size = u.u_offset;
 216:         ip->i_flag |= IUPD|ICHG;
 217:     } while(u.u_error == 0 && u.u_count != 0);
 218: }
 219: 
 220: 
 221: /*
 222:  * Move n bytes at byte location cp
 223:  * to/from (flag) the user/kernel (u.segflg)
 224:  * area starting at u.base.
 225:  * Update all the arguments by the number
 226:  * of bytes moved.
 227:  *
 228:  * There are 2 algorithms,
 229:  * if source address, dest address and count
 230:  * are all even in a user copy,
 231:  * then the machine language copyin/copyout
 232:  * is called.
 233:  * If not, its done byte by byte with
 234:  * cpass and passc.
 235:  */
 236: iomove(cp, n, flag)
 237: register caddr_t cp;
 238: register n;
 239: {
 240:     register t;
 241: 
 242:     if (n == 0)
 243:         return;
 244:     if(u.u_segflg != 1 && ((n | (int)cp | (int)u.u_base) & (NBPW-1)) == 0) {
 245:         if (flag == B_WRITE)
 246:             if (u.u_segflg == 0)
 247:                 t = copyin(u.u_base, (caddr_t)cp, n);
 248:             else
 249:                 t = copyiin(u.u_base, (caddr_t)cp, n);
 250:         else
 251:             if (u.u_segflg == 0)
 252:                 t = copyout((caddr_t)cp, u.u_base, n);
 253:             else
 254:                 t = copyiout((caddr_t)cp, u.u_base, n);
 255:         if (t) {
 256:             u.u_error = EFAULT;
 257:             return;
 258:         }
 259:         u.u_base += n;
 260:         u.u_offset += n;
 261:         u.u_count -= n;
 262:         return;
 263:     }
 264:     if (flag == B_WRITE) {
 265:         do {
 266:             if ((t = cpass()) < 0)
 267:                 return;
 268:             *cp++ = t;
 269:         } while (--n);
 270:     } else
 271:         do {
 272:             if(passc(*cp++) < 0)
 273:                 return;
 274:         } while (--n);
 275: }
Last modified: 1983-08-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 959
Valid CSS Valid XHTML 1.0 Strict