1: #
   2: /*
   3:  */
   4: 
   5: #include "../param.h"
   6: #include "../conf.h"
   7: #include "../inode.h"
   8: #include "../user.h"
   9: #include "../buf.h"
  10: #include "../systm.h"
  11: 
  12: /*
  13:  * Bmap defines the structure of file system storage
  14:  * by returning the physical block number on a device given the
  15:  * inode and the logical block number in a file.
  16:  * When convenient, it also leaves the physical
  17:  * block number of the next block of the file in rablock
  18:  * for use in read-ahead.
  19:  */
  20: bmap(ip, bn)
  21: struct inode *ip;
  22: int bn;
  23: {
  24:     register *bp, *bap, nb;
  25:     int *nbp, d, i;
  26: 
  27:     d = ip->i_dev;
  28:     if(bn & ~077777) {
  29:         u.u_error = EFBIG;
  30:         return(0);
  31:     }
  32: 
  33:     if((ip->i_mode&ILARG) == 0) {
  34: 
  35:         /*
  36: 		 * small file algorithm
  37: 		 */
  38: 
  39:         if((bn & ~7) != 0) {
  40: 
  41:             /*
  42: 			 * convert small to large
  43: 			 */
  44: 
  45:             if ((bp = alloc(d)) == NULL)
  46:                 return(NULL);
  47:             bap = bp->b_addr;
  48:             for(i=0; i<8; i++) {
  49:                 *bap++ = ip->i_addr[i];
  50:                 ip->i_addr[i] = 0;
  51:             }
  52:             ip->i_addr[0] = bp->b_blkno;
  53:             bdwrite(bp);
  54:             ip->i_mode =| ILARG;
  55:             goto large;
  56:         }
  57:         nb = ip->i_addr[bn];
  58:         if(nb == 0 && (bp = alloc(d)) != NULL) {
  59:             bdwrite(bp);
  60:             nb = bp->b_blkno;
  61:             ip->i_addr[bn] = nb;
  62:             ip->i_flag =| IUPD;
  63:         }
  64:         rablock = 0;
  65:         if (bn<7)
  66:             rablock = ip->i_addr[bn+1];
  67:         return(nb);
  68:     }
  69: 
  70:     /*
  71: 	 * large file algorithm
  72: 	 */
  73: 
  74:     large:
  75:     i = bn>>8;
  76:     if(bn & 0174000)
  77:         i = 7;
  78:     if((nb=ip->i_addr[i]) == 0) {
  79:         ip->i_flag =| IUPD;
  80:         if ((bp = alloc(d)) == NULL)
  81:             return(NULL);
  82:         ip->i_addr[i] = bp->b_blkno;
  83:     } else
  84:         bp = bread(d, nb);
  85:     bap = bp->b_addr;
  86: 
  87:     /*
  88: 	 * "huge" fetch of double indirect block
  89: 	 */
  90: 
  91:     if(i == 7) {
  92:         i = ((bn>>8) & 0377) - 7;
  93:         if((nb=bap[i]) == 0) {
  94:             if((nbp = alloc(d)) == NULL) {
  95:                 brelse(bp);
  96:                 return(NULL);
  97:             }
  98:             bap[i] = nbp->b_blkno;
  99:             bdwrite(bp);
 100:         } else {
 101:             brelse(bp);
 102:             nbp = bread(d, nb);
 103:         }
 104:         bp = nbp;
 105:         bap = bp->b_addr;
 106:     }
 107: 
 108:     /*
 109: 	 * normal indirect fetch
 110: 	 */
 111: 
 112:     i = bn & 0377;
 113:     if((nb=bap[i]) == 0 && (nbp = alloc(d)) != NULL) {
 114:         nb = nbp->b_blkno;
 115:         bap[i] = nb;
 116:         bdwrite(nbp);
 117:         bdwrite(bp);
 118:     } else
 119:         brelse(bp);
 120:     rablock = 0;
 121:     if(i < 255)
 122:         rablock = bap[i+1];
 123:     return(nb);
 124: }
 125: 
 126: /*
 127:  * Pass back  c  to the user at his location u_base;
 128:  * update u_base, u_count, and u_offset.  Return -1
 129:  * on the last character of the user's read.
 130:  * u_base is in the user address space unless u_segflg is set.
 131:  */
 132: passc(c)
 133: char c;
 134: {
 135: 
 136:     if(u.u_segflg)
 137:         *u.u_base = c; else
 138:         if(subyte(u.u_base, c) < 0) {
 139:             u.u_error = EFAULT;
 140:             return(-1);
 141:         }
 142:     u.u_count--;
 143:     if(++u.u_offset[1] == 0)
 144:         u.u_offset[0]++;
 145:     u.u_base++;
 146:     return(u.u_count == 0? -1: 0);
 147: }
 148: 
 149: /*
 150:  * Pick up and return the next character from the user's
 151:  * write call at location u_base;
 152:  * update u_base, u_count, and u_offset.  Return -1
 153:  * when u_count is exhausted.  u_base is in the user's
 154:  * address space unless u_segflg is set.
 155:  */
 156: cpass()
 157: {
 158:     register c;
 159: 
 160:     if(u.u_count == 0)
 161:         return(-1);
 162:     if(u.u_segflg)
 163:         c = *u.u_base; else
 164:         if((c=fubyte(u.u_base)) < 0) {
 165:             u.u_error = EFAULT;
 166:             return(-1);
 167:         }
 168:     u.u_count--;
 169:     if(++u.u_offset[1] == 0)
 170:         u.u_offset[0]++;
 171:     u.u_base++;
 172:     return(c&0377);
 173: }
 174: 
 175: /*
 176:  * Routine which sets a user error; placed in
 177:  * illegal entries in the bdevsw and cdevsw tables.
 178:  */
 179: nodev()
 180: {
 181: 
 182:     u.u_error = ENODEV;
 183: }
 184: 
 185: /*
 186:  * Null routine; placed in insignificant entries
 187:  * in the bdevsw and cdevsw tables.
 188:  */
 189: nulldev()
 190: {
 191: }
 192: 
 193: /*
 194:  * copy count words from from to to.
 195:  */
 196: bcopy(from, to, count)
 197: int *from, *to;
 198: {
 199:     register *a, *b, c;
 200: 
 201:     a = from;
 202:     b = to;
 203:     c = count;
 204:     do
 205:         *b++ = *a++;
 206:     while(--c);
 207: }

Defined functions

bcopy defined in line 196; used 7 times
bmap defined in line 20; used 3 times
nodev defined in line 179; never used
nulldev defined in line 189; never used
passc defined in line 132; used 5 times
Last modified: 1975-07-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 901
Valid CSS Valid XHTML 1.0 Strict