1: #
   2: /*
   3:  */
   4: 
   5: #include "../param.h"
   6: #include "../systm.h"
   7: #include "../filsys.h"
   8: #include "../conf.h"
   9: #include "../buf.h"
  10: #include "../inode.h"
  11: #include "../user.h"
  12: 
  13: /*
  14:  * iinit is called once (from main)
  15:  * very early in initialization.
  16:  * It reads the root's super block
  17:  * and initializes the current date
  18:  * from the last modified date.
  19:  *
  20:  * panic: iinit -- cannot read the super
  21:  * block. Usually because of an IO error.
  22:  */
  23: iinit()
  24: {
  25:     register *cp, *bp;
  26: 
  27:     (*bdevsw[rootdev.d_major].d_open)(rootdev, 1);
  28:     bp = bread(rootdev, 1);
  29:     cp = getblk(NODEV);
  30:     if(u.u_error)
  31:         panic("iinit");
  32:     bcopy(bp->b_addr, cp->b_addr, 256);
  33:     brelse(bp);
  34:     mount[0].m_bufp = cp;
  35:     mount[0].m_dev = rootdev;
  36:     cp = cp->b_addr;
  37:     cp->s_flock = 0;
  38:     cp->s_ilock = 0;
  39:     cp->s_ronly = 0;
  40:     time[0] = cp->s_time[0];
  41:     time[1] = cp->s_time[1];
  42: }
  43: 
  44: /*
  45:  * alloc will obtain the next available
  46:  * free disk block from the free list of
  47:  * the specified device.
  48:  * The super block has up to 100 remembered
  49:  * free blocks; the last of these is read to
  50:  * obtain 100 more . . .
  51:  *
  52:  * no space on dev x/y -- when
  53:  * the free list is exhausted.
  54:  */
  55: alloc(dev)
  56: {
  57:     int bno;
  58:     register *bp, *ip, *fp;
  59: 
  60:     fp = getfs(dev);
  61:     while(fp->s_flock)
  62:         sleep(&fp->s_flock, PINOD);
  63:     do {
  64:         if(fp->s_nfree <= 0)
  65:             goto nospace;
  66:         bno = fp->s_free[--fp->s_nfree];
  67:         if(bno == 0)
  68:             goto nospace;
  69:     } while (badblock(fp, bno, dev));
  70:     if(fp->s_nfree <= 0) {
  71:         fp->s_flock++;
  72:         bp = bread(dev, bno);
  73:         ip = bp->b_addr;
  74:         fp->s_nfree = *ip++;
  75:         bcopy(ip, fp->s_free, 100);
  76:         brelse(bp);
  77:         fp->s_flock = 0;
  78:         wakeup(&fp->s_flock);
  79:     }
  80:     bp = getblk(dev, bno);
  81:     clrbuf(bp);
  82:     fp->s_fmod = 1;
  83:     return(bp);
  84: 
  85: nospace:
  86:     fp->s_nfree = 0;
  87:     prdev("no space", dev);
  88:     u.u_error = ENOSPC;
  89:     return(NULL);
  90: }
  91: 
  92: /*
  93:  * place the specified disk block
  94:  * back on the free list of the
  95:  * specified device.
  96:  */
  97: free(dev, bno)
  98: {
  99:     register *fp, *bp, *ip;
 100: 
 101:     fp = getfs(dev);
 102:     fp->s_fmod = 1;
 103:     while(fp->s_flock)
 104:         sleep(&fp->s_flock, PINOD);
 105:     if (badblock(fp, bno, dev))
 106:         return;
 107:     if(fp->s_nfree <= 0) {
 108:         fp->s_nfree = 1;
 109:         fp->s_free[0] = 0;
 110:     }
 111:     if(fp->s_nfree >= 100) {
 112:         fp->s_flock++;
 113:         bp = getblk(dev, bno);
 114:         ip = bp->b_addr;
 115:         *ip++ = fp->s_nfree;
 116:         bcopy(fp->s_free, ip, 100);
 117:         fp->s_nfree = 0;
 118:         bwrite(bp);
 119:         fp->s_flock = 0;
 120:         wakeup(&fp->s_flock);
 121:     }
 122:     fp->s_free[fp->s_nfree++] = bno;
 123:     fp->s_fmod = 1;
 124: }
 125: 
 126: /*
 127:  * Check that a block number is in the
 128:  * range between the I list and the size
 129:  * of the device.
 130:  * This is used mainly to check that a
 131:  * garbage file system has not been mounted.
 132:  *
 133:  * bad block on dev x/y -- not in range
 134:  */
 135: badblock(afp, abn, dev)
 136: {
 137:     register struct filsys *fp;
 138:     register char *bn;
 139: 
 140:     fp = afp;
 141:     bn = abn;
 142:     if (bn < fp->s_isize+2 || bn >= fp->s_fsize) {
 143:         prdev("bad block", dev);
 144:         return(1);
 145:     }
 146:     return(0);
 147: }
 148: 
 149: /*
 150:  * Allocate an unused I node
 151:  * on the specified device.
 152:  * Used with file creation.
 153:  * The algorithm keeps up to
 154:  * 100 spare I nodes in the
 155:  * super block. When this runs out,
 156:  * a linear search through the
 157:  * I list is instituted to pick
 158:  * up 100 more.
 159:  */
 160: ialloc(dev)
 161: {
 162:     register *fp, *bp, *ip;
 163:     int i, j, k, ino;
 164: 
 165:     fp = getfs(dev);
 166:     while(fp->s_ilock)
 167:         sleep(&fp->s_ilock, PINOD);
 168: loop:
 169:     if(fp->s_ninode > 0) {
 170:         ino = fp->s_inode[--fp->s_ninode];
 171:         ip = iget(dev, ino);
 172:         if (ip==NULL)
 173:             return(NULL);
 174:         if(ip->i_mode == 0) {
 175:             for(bp = &ip->i_mode; bp < &ip->i_addr[8];)
 176:                 *bp++ = 0;
 177:             fp->s_fmod = 1;
 178:             return(ip);
 179:         }
 180:         /*
 181: 		 * Inode was allocated after all.
 182: 		 * Look some more.
 183: 		 */
 184:         iput(ip);
 185:         goto loop;
 186:     }
 187:     fp->s_ilock++;
 188:     ino = 0;
 189:     for(i=0; i<fp->s_isize; i++) {
 190:         bp = bread(dev, i+2);
 191:         ip = bp->b_addr;
 192:         for(j=0; j<256; j=+16) {
 193:             ino++;
 194:             if(ip[j] != 0)
 195:                 continue;
 196:             for(k=0; k<NINODE; k++)
 197:             if(dev==inode[k].i_dev && ino==inode[k].i_number)
 198:                 goto cont;
 199:             fp->s_inode[fp->s_ninode++] = ino;
 200:             if(fp->s_ninode >= 100)
 201:                 break;
 202:         cont:;
 203:         }
 204:         brelse(bp);
 205:         if(fp->s_ninode >= 100)
 206:             break;
 207:     }
 208:     fp->s_ilock = 0;
 209:     wakeup(&fp->s_ilock);
 210:     if (fp->s_ninode > 0)
 211:         goto loop;
 212:     prdev("Out of inodes", dev);
 213:     u.u_error = ENOSPC;
 214:     return(NULL);
 215: }
 216: 
 217: /*
 218:  * Free the specified I node
 219:  * on the specified device.
 220:  * The algorithm stores up
 221:  * to 100 I nodes in the super
 222:  * block and throws away any more.
 223:  */
 224: ifree(dev, ino)
 225: {
 226:     register *fp;
 227: 
 228:     fp = getfs(dev);
 229:     if(fp->s_ilock)
 230:         return;
 231:     if(fp->s_ninode >= 100)
 232:         return;
 233:     fp->s_inode[fp->s_ninode++] = ino;
 234:     fp->s_fmod = 1;
 235: }
 236: 
 237: /*
 238:  * getfs maps a device number into
 239:  * a pointer to the incore super
 240:  * block.
 241:  * The algorithm is a linear
 242:  * search through the mount table.
 243:  * A consistency check of the
 244:  * in core free-block and i-node
 245:  * counts.
 246:  *
 247:  * bad count on dev x/y -- the count
 248:  *	check failed. At this point, all
 249:  *	the counts are zeroed which will
 250:  *	almost certainly lead to "no space"
 251:  *	diagnostic
 252:  * panic: no fs -- the device is not mounted.
 253:  *	this "cannot happen"
 254:  */
 255: getfs(dev)
 256: {
 257:     register struct mount *p;
 258:     register char *n1, *n2;
 259: 
 260:     for(p = &mount[0]; p < &mount[NMOUNT]; p++)
 261:     if(p->m_bufp != NULL && p->m_dev == dev) {
 262:         p = p->m_bufp->b_addr;
 263:         n1 = p->s_nfree;
 264:         n2 = p->s_ninode;
 265:         if(n1 > 100 || n2 > 100) {
 266:             prdev("bad count", dev);
 267:             p->s_nfree = 0;
 268:             p->s_ninode = 0;
 269:         }
 270:         return(p);
 271:     }
 272:     panic("no fs");
 273: }
 274: 
 275: /*
 276:  * update is the internal name of
 277:  * 'sync'. It goes through the disk
 278:  * queues to initiate sandbagged IO;
 279:  * goes through the I nodes to write
 280:  * modified nodes; and it goes through
 281:  * the mount table to initiate modified
 282:  * super blocks.
 283:  */
 284: update()
 285: {
 286:     register struct inode *ip;
 287:     register struct mount *mp;
 288:     register *bp;
 289: 
 290:     if(updlock)
 291:         return;
 292:     updlock++;
 293:     for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
 294:         if(mp->m_bufp != NULL) {
 295:             ip = mp->m_bufp->b_addr;
 296:             if(ip->s_fmod==0 || ip->s_ilock!=0 ||
 297:                ip->s_flock!=0 || ip->s_ronly!=0)
 298:                 continue;
 299:             bp = getblk(mp->m_dev, 1);
 300:             ip->s_fmod = 0;
 301:             ip->s_time[0] = time[0];
 302:             ip->s_time[1] = time[1];
 303:             bcopy(ip, bp->b_addr, 256);
 304:             bwrite(bp);
 305:         }
 306:     for(ip = &inode[0]; ip < &inode[NINODE]; ip++)
 307:         if((ip->i_flag&ILOCK) == 0) {
 308:             ip->i_flag =| ILOCK;
 309:             iupdat(ip, time);
 310:             prele(ip);
 311:         }
 312:     updlock = 0;
 313:     bflush(NODEV);
 314: }

Defined functions

alloc defined in line 55; used 5 times
badblock defined in line 135; used 2 times
free defined in line 97; used 3 times
getfs defined in line 255; used 6 times
ialloc defined in line 160; used 2 times
ifree defined in line 224; used 1 times
iinit defined in line 23; used 1 times
update defined in line 284; used 3 times
Last modified: 1975-07-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1061
Valid CSS Valid XHTML 1.0 Strict