1: /*
   2:  * Copyright (c) 1982, 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)ufs_subr.c	7.1 (Berkeley) 6/5/86
   7:  */
   8: 
   9: #ifdef KERNEL
  10: #include "param.h"
  11: #include "systm.h"
  12: #include "mount.h"
  13: #include "fs.h"
  14: #include "buf.h"
  15: #include "inode.h"
  16: #include "dir.h"
  17: #include "user.h"
  18: #include "quota.h"
  19: #include "kernel.h"
  20: #else
  21: #include <sys/param.h>
  22: #include <sys/systm.h>
  23: #include <sys/mount.h>
  24: #include <sys/fs.h>
  25: #include <sys/buf.h>
  26: #include <sys/inode.h>
  27: #include <sys/dir.h>
  28: #include <sys/user.h>
  29: #include <sys/quota.h>
  30: #endif
  31: 
  32: #ifdef KERNEL
  33: int syncprt = 0;
  34: 
  35: /*
  36:  * Update is the internal name of 'sync'.  It goes through the disk
  37:  * queues to initiate sandbagged IO; goes through the inodes to write
  38:  * modified nodes; and it goes through the mount table to initiate
  39:  * the writing of the modified super blocks.
  40:  */
  41: update()
  42: {
  43:     register struct inode *ip;
  44:     register struct mount *mp;
  45:     struct fs *fs;
  46: 
  47:     if (syncprt)
  48:         bufstats();
  49:     if (updlock)
  50:         return;
  51:     updlock++;
  52:     /*
  53: 	 * Write back modified superblocks.
  54: 	 * Consistency check that the superblock
  55: 	 * of each file system is still in the buffer cache.
  56: 	 */
  57:     for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++) {
  58:         if (mp->m_bufp == NULL || mp->m_dev == NODEV)
  59:             continue;
  60:         fs = mp->m_bufp->b_un.b_fs;
  61:         if (fs->fs_fmod == 0)
  62:             continue;
  63:         if (fs->fs_ronly != 0) {        /* XXX */
  64:             printf("fs = %s\n", fs->fs_fsmnt);
  65:             panic("update: rofs mod");
  66:         }
  67:         fs->fs_fmod = 0;
  68:         fs->fs_time = time.tv_sec;
  69:         sbupdate(mp);
  70:     }
  71:     /*
  72: 	 * Write back each (modified) inode.
  73: 	 */
  74:     for (ip = inode; ip < inodeNINODE; ip++) {
  75:         if ((ip->i_flag & ILOCKED) != 0 || ip->i_count == 0 ||
  76:             (ip->i_flag & (IMOD|IACC|IUPD|ICHG)) == 0)
  77:             continue;
  78:         ip->i_flag |= ILOCKED;
  79:         ip->i_count++;
  80:         iupdat(ip, &time, &time, 0);
  81:         iput(ip);
  82:     }
  83:     updlock = 0;
  84:     /*
  85: 	 * Force stale buffer cache information to be flushed,
  86: 	 * for all devices.
  87: 	 */
  88:     bflush(NODEV);
  89: }
  90: 
  91: /*
  92:  * Flush all the blocks associated with an inode.
  93:  * There are two strategies based on the size of the file;
  94:  * large files are those with more than (nbuf / 2) blocks.
  95:  * Large files
  96:  * 	Walk through the buffer pool and push any dirty pages
  97:  *	associated with the device on which the file resides.
  98:  * Small files
  99:  *	Look up each block in the file to see if it is in the
 100:  *	buffer pool writing any that are found to disk.
 101:  *	Note that we make a more stringent check of
 102:  *	writing out any block in the buffer pool that may
 103:  *	overlap the inode. This brings the inode up to
 104:  *	date with recent mods to the cooked device.
 105:  */
 106: syncip(ip)
 107:     register struct inode *ip;
 108: {
 109:     register struct fs *fs;
 110:     register struct buf *bp;
 111:     struct buf *lastbufp;
 112:     long lbn, lastlbn;
 113:     int s;
 114:     daddr_t blkno;
 115: 
 116:     fs = ip->i_fs;
 117:     lastlbn = howmany(ip->i_size, fs->fs_bsize);
 118:     if (lastlbn < nbuf / 2) {
 119:         for (lbn = 0; lbn < lastlbn; lbn++) {
 120:             blkno = fsbtodb(fs, bmap(ip, lbn, B_READ));
 121:             blkflush(ip->i_dev, blkno, blksize(fs, ip, lbn));
 122:         }
 123:     } else {
 124:         lastbufp = &buf[nbuf];
 125:         for (bp = buf; bp < lastbufp; bp++) {
 126:             if (bp->b_dev != ip->i_dev ||
 127:                 (bp->b_flags & B_DELWRI) == 0)
 128:                 continue;
 129:             s = splbio();
 130:             if (bp->b_flags & B_BUSY) {
 131:                 bp->b_flags |= B_WANTED;
 132:                 sleep((caddr_t)bp, PRIBIO+1);
 133:                 splx(s);
 134:                 bp--;
 135:                 continue;
 136:             }
 137:             splx(s);
 138:             notavail(bp);
 139:             bwrite(bp);
 140:         }
 141:     }
 142:     ip->i_flag |= ICHG;
 143:     iupdat(ip, &time, &time, 1);
 144: }
 145: #endif
 146: 
 147: extern  int around[9];
 148: extern  int inside[9];
 149: extern  u_char *fragtbl[];
 150: 
 151: /*
 152:  * Update the frsum fields to reflect addition or deletion
 153:  * of some frags.
 154:  */
 155: fragacct(fs, fragmap, fraglist, cnt)
 156:     struct fs *fs;
 157:     int fragmap;
 158:     long fraglist[];
 159:     int cnt;
 160: {
 161:     int inblk;
 162:     register int field, subfield;
 163:     register int siz, pos;
 164: 
 165:     inblk = (int)(fragtbl[fs->fs_frag][fragmap]) << 1;
 166:     fragmap <<= 1;
 167:     for (siz = 1; siz < fs->fs_frag; siz++) {
 168:         if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0)
 169:             continue;
 170:         field = around[siz];
 171:         subfield = inside[siz];
 172:         for (pos = siz; pos <= fs->fs_frag; pos++) {
 173:             if ((fragmap & field) == subfield) {
 174:                 fraglist[siz] += cnt;
 175:                 pos += siz;
 176:                 field <<= siz;
 177:                 subfield <<= siz;
 178:             }
 179:             field <<= 1;
 180:             subfield <<= 1;
 181:         }
 182:     }
 183: }
 184: 
 185: #ifdef KERNEL
 186: /*
 187:  * Check that a specified block number is in range.
 188:  */
 189: badblock(fs, bn)
 190:     register struct fs *fs;
 191:     daddr_t bn;
 192: {
 193: 
 194:     if ((unsigned)bn >= fs->fs_size) {
 195:         printf("bad block %d, ", bn);
 196:         fserr(fs, "bad block");
 197:         return (1);
 198:     }
 199:     return (0);
 200: }
 201: #endif
 202: 
 203: /*
 204:  * block operations
 205:  *
 206:  * check if a block is available
 207:  */
 208: isblock(fs, cp, h)
 209:     struct fs *fs;
 210:     unsigned char *cp;
 211:     daddr_t h;
 212: {
 213:     unsigned char mask;
 214: 
 215:     switch ((int)fs->fs_frag) {
 216:     case 8:
 217:         return (cp[h] == 0xff);
 218:     case 4:
 219:         mask = 0x0f << ((h & 0x1) << 2);
 220:         return ((cp[h >> 1] & mask) == mask);
 221:     case 2:
 222:         mask = 0x03 << ((h & 0x3) << 1);
 223:         return ((cp[h >> 2] & mask) == mask);
 224:     case 1:
 225:         mask = 0x01 << (h & 0x7);
 226:         return ((cp[h >> 3] & mask) == mask);
 227:     default:
 228:         panic("isblock");
 229:         return (NULL);
 230:     }
 231: }
 232: 
 233: /*
 234:  * take a block out of the map
 235:  */
 236: clrblock(fs, cp, h)
 237:     struct fs *fs;
 238:     u_char *cp;
 239:     daddr_t h;
 240: {
 241: 
 242:     switch ((int)fs->fs_frag) {
 243:     case 8:
 244:         cp[h] = 0;
 245:         return;
 246:     case 4:
 247:         cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
 248:         return;
 249:     case 2:
 250:         cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
 251:         return;
 252:     case 1:
 253:         cp[h >> 3] &= ~(0x01 << (h & 0x7));
 254:         return;
 255:     default:
 256:         panic("clrblock");
 257:     }
 258: }
 259: 
 260: /*
 261:  * put a block into the map
 262:  */
 263: setblock(fs, cp, h)
 264:     struct fs *fs;
 265:     unsigned char *cp;
 266:     daddr_t h;
 267: {
 268: 
 269:     switch ((int)fs->fs_frag) {
 270: 
 271:     case 8:
 272:         cp[h] = 0xff;
 273:         return;
 274:     case 4:
 275:         cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
 276:         return;
 277:     case 2:
 278:         cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
 279:         return;
 280:     case 1:
 281:         cp[h >> 3] |= (0x01 << (h & 0x7));
 282:         return;
 283:     default:
 284:         panic("setblock");
 285:     }
 286: }
 287: 
 288: #ifdef KERNEL
 289: /*
 290:  * Getfs maps a device number into a pointer to the incore super block.
 291:  *
 292:  * The algorithm is a linear search through the mount table. A
 293:  * consistency check of the super block magic number is performed.
 294:  *
 295:  * panic: no fs -- the device is not mounted.
 296:  *	this "cannot happen"
 297:  */
 298: struct fs *
 299: getfs(dev)
 300:     dev_t dev;
 301: {
 302:     register struct mount *mp;
 303:     register struct fs *fs;
 304: 
 305:     for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++) {
 306:         if (mp->m_bufp == NULL || mp->m_dev != dev)
 307:             continue;
 308:         fs = mp->m_bufp->b_un.b_fs;
 309:         if (fs->fs_magic != FS_MAGIC) {
 310:             printf("dev = 0x%x, fs = %s\n", dev, fs->fs_fsmnt);
 311:             panic("getfs: bad magic");
 312:         }
 313:         return (fs);
 314:     }
 315:     printf("dev = 0x%x\n", dev);
 316:     panic("getfs: no fs");
 317:     return (NULL);
 318: }
 319: 
 320: /*
 321:  * Getfsx returns the index in the file system
 322:  * table of the specified device.  The swap device
 323:  * is also assigned a pseudo-index.  The index may
 324:  * be used as a compressed indication of the location
 325:  * of a block, recording
 326:  *	<getfsx(dev),blkno>
 327:  * rather than
 328:  *	<dev, blkno>
 329:  * provided the information need remain valid only
 330:  * as long as the file system is mounted.
 331:  */
 332: getfsx(dev)
 333:     dev_t dev;
 334: {
 335:     register struct mount *mp;
 336: 
 337:     if (dev == swapdev)
 338:         return (MSWAPX);
 339:     for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
 340:         if (mp->m_dev == dev)
 341:             return (mp - &mount[0]);
 342:     return (-1);
 343: }
 344: 
 345: /*
 346:  * Print out statistics on the current allocation of the buffer pool.
 347:  * Can be enabled to print out on every ``sync'' by setting "syncprt"
 348:  * above.
 349:  */
 350: bufstats()
 351: {
 352:     int s, i, j, count;
 353:     register struct buf *bp, *dp;
 354:     int counts[MAXBSIZE/CLBYTES+1];
 355:     static char *bname[BQUEUES] = { "LOCKED", "LRU", "AGE", "EMPTY" };
 356: 
 357:     for (bp = bfreelist, i = 0; bp < &bfreelist[BQUEUES]; bp++, i++) {
 358:         count = 0;
 359:         for (j = 0; j <= MAXBSIZE/CLBYTES; j++)
 360:             counts[j] = 0;
 361:         s = splbio();
 362:         for (dp = bp->av_forw; dp != bp; dp = dp->av_forw) {
 363:             counts[dp->b_bufsize/CLBYTES]++;
 364:             count++;
 365:         }
 366:         splx(s);
 367:         printf("%s: total-%d", bname[i], count);
 368:         for (j = 0; j <= MAXBSIZE/CLBYTES; j++)
 369:             if (counts[j] != 0)
 370:                 printf(", %d-%d", j * CLBYTES, counts[j]);
 371:         printf("\n");
 372:     }
 373: }
 374: #endif
 375: 
 376: #if !defined(vax) || defined(VAX630)
 377: /*
 378:  * C definitions of special vax instructions.
 379:  */
 380: scanc(size, cp, table, mask)
 381:     u_int size;
 382:     register u_char *cp, table[];
 383:     register u_char mask;
 384: {
 385:     register u_char *end = &cp[size];
 386: 
 387:     while (cp < end && (table[*cp] & mask) == 0)
 388:         cp++;
 389:     return (end - cp);
 390: }
 391: 
 392: #endif
 393: #if !defined(vax)
 394: 
 395: skpc(mask, size, cp)
 396:     register u_char mask;
 397:     u_int size;
 398:     register u_char *cp;
 399: {
 400:     register u_char *end = &cp[size];
 401: 
 402:     while (cp < end && *cp == mask)
 403:         cp++;
 404:     return (end - cp);
 405: }
 406: 
 407: locc(mask, size, cp)
 408:     register u_char mask;
 409:     u_int size;
 410:     register u_char *cp;
 411: {
 412:     register u_char *end = &cp[size];
 413: 
 414:     while (cp < end && *cp != mask)
 415:         cp++;
 416:     return (end - cp);
 417: }
 418: #endif vax

Defined functions

badblock defined in line 189; used 1 times
bufstats defined in line 350; used 1 times
  • in line 48
clrblock defined in line 236; used 1 times
fragacct defined in line 155; used 2 times
getfs defined in line 298; used 6 times
isblock defined in line 208; used 4 times
locc defined in line 407; used 2 times
scanc defined in line 380; used 3 times
setblock defined in line 263; used 1 times
skpc defined in line 395; used 2 times
syncip defined in line 106; used 2 times

Defined variables

syncprt defined in line 33; used 1 times
  • in line 47
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1432
Valid CSS Valid XHTML 1.0 Strict