|
|
1.1 ! root 1: /* $Header: /newbits/286_KERNEL/USRSRC/coh/RCS/fs2.c,v 1.1 92/01/09 13:28:39 bin Exp Locker: bin $ */ ! 2: /* (lgl- ! 3: * The information contained herein is a trade secret of Mark Williams ! 4: * Company, and is confidential information. It is provided under a ! 5: * license agreement, and may be copied or disclosed only under the ! 6: * terms of that agreement. Any reproduction or disclosure of this ! 7: * material without the express written authorization of Mark Williams ! 8: * Company or persuant to the license agreement is unlawful. ! 9: * ! 10: * COHERENT Version 2.3.37 ! 11: * Copyright (c) 1982, 1983, 1984. ! 12: * An unpublished work by Mark Williams Company, Chicago. ! 13: * All rights reserved. ! 14: -lgl) */ ! 15: /* ! 16: * Coherent. ! 17: * Filesystem (disk inodes). ! 18: * ! 19: * $Log: fs2.c,v $ ! 20: * Revision 1.1 92/01/09 13:28:39 bin ! 21: * Initial revision ! 22: * ! 23: * Revision 1.1 88/03/24 16:13:51 src ! 24: * Initial revision ! 25: * ! 26: * 87/11/25 Allan Cornish /usr/src/sys/coh/fs2.c ! 27: * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr. ! 28: * ! 29: * 87/04/29 Allan Cornish /usr/src/sys/coh/fs2.c ! 30: * Fsminit panic messages now specify the root major and minor device. ! 31: * ! 32: * 86/11/19 Allan Cornish /usr/src/sys/coh/fs2.c ! 33: * setacct() initializes the (new) (IO).io_flag field to 0. ! 34: * ! 35: * 85/08/08 Allan Cornish ! 36: * ialloc() erroneously did a brelease(NULL) if bclaim() returned NULL. ! 37: * also, sbp->s_fmod was set BEFORE the in-core inode table was updated. ! 38: * This created a critical race with msync() (called by sync system call). ! 39: * ! 40: * 85/04/17 Allan Cornish ! 41: * eliminated test for rootdev in msync() ! 42: */ ! 43: #include <sys/coherent.h> ! 44: #include <acct.h> ! 45: #include <sys/buf.h> ! 46: #include <canon.h> ! 47: #include <sys/con.h> ! 48: #include <errno.h> ! 49: #include <sys/filsys.h> ! 50: #include <sys/ino.h> ! 51: #include <sys/inode.h> ! 52: #include <sys/io.h> ! 53: #include <sys/mount.h> ! 54: #include <sys/proc.h> ! 55: #include <sys/stat.h> ! 56: #include <sys/uproc.h> ! 57: ! 58: /* ! 59: * Initialise filesystem. ! 60: */ ! 61: fsminit() ! 62: { ! 63: register MOUNT *mp; ! 64: ! 65: /* ! 66: * Mount the root file system. ! 67: */ ! 68: if ( (mp = fsmount(rootdev, ronflag)) == NULL ) ! 69: panic( "fsminit: no rootdev(%d,%d)", ! 70: major(rootdev), minor(rootdev) ); ! 71: ! 72: /* ! 73: * Set system time from the super block. ! 74: */ ! 75: timer.t_time = mp->m_super.s_time; ! 76: ! 77: /* ! 78: * Access the root directory. ! 79: */ ! 80: if ( (u.u_rdir = iattach(rootdev, ROOTIN)) == NULL ) ! 81: panic( "fsminit: no / on rootdev(%d,%d)", ! 82: major(rootdev), minor(rootdev) ); ! 83: ! 84: /* ! 85: * Record current directory. ! 86: */ ! 87: u.u_cdir = u.u_rdir; ! 88: u.u_cdir->i_refc++; ! 89: iunlock(u.u_rdir); ! 90: } ! 91: ! 92: /* ! 93: * Mount the given device. ! 94: */ ! 95: MOUNT * ! 96: fsmount(dev, f) ! 97: register dev_t dev; ! 98: { ! 99: register MOUNT *mp; ! 100: register BUF *bp; ! 101: ! 102: if ((mp=kalloc(sizeof(MOUNT))) == NULL) ! 103: return (NULL); ! 104: dopen(dev, (f?IPR:IPR|IPW), DFBLK); ! 105: if (u.u_error != 0) { ! 106: kfree(mp); ! 107: return (NULL); ! 108: } ! 109: if ((bp=bread(dev, (daddr_t)SUPERI, 1)) == NULL) { ! 110: dclose(dev); ! 111: kfree(mp); ! 112: return (NULL); ! 113: } ! 114: kkcopy(FP_OFF(bp->b_faddr), &mp->m_super, sizeof(struct filsys)); ! 115: brelease(bp); ! 116: cansuper(&mp->m_super); ! 117: mp->m_ip = NULL; ! 118: mp->m_dev = dev; ! 119: mp->m_flag = f; ! 120: mp->m_super.s_fmod = 0; ! 121: mp->m_next = mountp; ! 122: mountp = mp; ! 123: return (mp); ! 124: } ! 125: ! 126: /* ! 127: * Canonize a super block. ! 128: */ ! 129: cansuper(fsp) ! 130: register struct filsys *fsp; ! 131: { ! 132: register int i; ! 133: ! 134: canint(fsp->s_isize); ! 135: candaddr(fsp->s_fsize); ! 136: canshort(fsp->s_nfree); ! 137: for (i=0; i<NICFREE; i++) ! 138: candaddr(fsp->s_free[i]); ! 139: canshort(fsp->s_ninode); ! 140: for (i=0; i<NICINOD; i++) ! 141: canino(fsp->s_inode[i]); ! 142: cantime(fsp->s_time); ! 143: candaddr(fsp->s_tfree); ! 144: canino(fsp->s_tinode); ! 145: canshort(fsp->s_m); ! 146: canshort(fsp->s_n); ! 147: canlong(fsp->s_unique); ! 148: } ! 149: ! 150: /* ! 151: * Given a pointer to a mount entry, write out all inodes on that device. ! 152: */ ! 153: msync(mp) ! 154: register MOUNT *mp; ! 155: { ! 156: register struct filsys *sbp; ! 157: register BUF *bp; ! 158: ! 159: if ((mp->m_flag&MFRON) != 0) ! 160: return; ! 161: isync(mp->m_dev); ! 162: sbp = &mp->m_super; ! 163: if (sbp->s_fmod==0) ! 164: return; ! 165: bp = bclaim(mp->m_dev, (daddr_t)SUPERI); ! 166: sbp->s_time = timer.t_time; ! 167: sbp->s_fmod = 0; ! 168: kkcopy(sbp, FP_OFF(bp->b_faddr), sizeof(*sbp)); ! 169: cansuper(FP_OFF(bp->b_faddr)); ! 170: bwrite(bp, 1); ! 171: brelease(bp); ! 172: } ! 173: ! 174: /* ! 175: * Return the mount entry for the given device. If `f' is not set ! 176: * and the device is read only, don't set the error status. ! 177: */ ! 178: MOUNT * ! 179: getment(dev, f) ! 180: register dev_t dev; ! 181: { ! 182: register MOUNT *mp; ! 183: ! 184: for (mp=mountp; mp!=NULL; mp=mp->m_next) { ! 185: if (mp->m_dev != dev) ! 186: continue; ! 187: if ((mp->m_flag&MFRON) != 0) { ! 188: if (f != 0) ! 189: u.u_error = EROFS; ! 190: return (NULL); ! 191: } ! 192: return (mp); ! 193: } ! 194: panic("getment: dev=0x%x", dev); ! 195: } ! 196: ! 197: /* ! 198: * Allocate a new inode with the given mode. The returned inode is locked. ! 199: */ ! 200: INODE * ! 201: ialloc(dev, mode) ! 202: dev_t dev; ! 203: unsigned mode; ! 204: { ! 205: register struct dinode *dip; ! 206: register struct filsys *sbp; ! 207: register ino_t *inop; ! 208: register ino_t ino; ! 209: register BUF *bp; ! 210: register daddr_t b; ! 211: register struct dinode *dipe; ! 212: register ino_t *inope; ! 213: register MOUNT *mp; ! 214: register INODE *ip; ! 215: ! 216: if ((mp=getment(dev, 1)) == NULL) ! 217: return (NULL); ! 218: sbp = &mp->m_super; ! 219: for (;;) { ! 220: lock(mp->m_ilock); ! 221: if (sbp->s_ninode == 0) { ! 222: ino = 1; ! 223: inop = sbp->s_inode; ! 224: inope = &sbp->s_inode[NICINOD]; ! 225: for (b=INODEI; b<sbp->s_isize; b++) { ! 226: if (bad(dev, b)) { ! 227: ino += INOPB; ! 228: continue; ! 229: } ! 230: if ((bp=bread(dev, b, 1)) == NULL) { ! 231: ino += INOPB; ! 232: continue; ! 233: } ! 234: dip = FP_OFF(bp->b_faddr); ! 235: dipe = &dip[INOPB]; ! 236: for (; dip<dipe; dip++, ino++) { ! 237: if (dip->di_mode != 0) ! 238: continue; ! 239: if (inop >= inope) ! 240: break; ! 241: *inop++ = ino; ! 242: } ! 243: brelease(bp); ! 244: if (inop >= inope) ! 245: break; ! 246: } ! 247: sbp->s_ninode = inop - sbp->s_inode; ! 248: if (sbp->s_ninode == 0) { ! 249: sbp->s_tinode = 0; ! 250: unlock(mp->m_ilock); ! 251: devmsg(dev, "Out of inodes"); ! 252: u.u_error = ENOSPC; ! 253: return (NULL); ! 254: } ! 255: } ! 256: ino = sbp->s_inode[--sbp->s_ninode]; ! 257: --sbp->s_tinode; ! 258: sbp->s_fmod = 1; ! 259: unlock(mp->m_ilock); ! 260: if ((ip=iattach(dev, ino)) != NULL) { ! 261: if (ip->i_mode != 0) { ! 262: devmsg(dev, "Inode %u busy", ino); ! 263: idetach(ip); ! 264: continue; ! 265: } ! 266: ip->i_flag = 0; ! 267: ip->i_mode = mode; ! 268: ip->i_nlink = 0; ! 269: ip->i_uid = u.u_uid; ! 270: ip->i_gid = u.u_gid; ! 271: } ! 272: return (ip); ! 273: } ! 274: } ! 275: ! 276: /* ! 277: * Free the inode `ino' on device `dev'. ! 278: */ ! 279: ifree(dev, ino) ! 280: dev_t dev; ! 281: ino_t ino; ! 282: { ! 283: register struct filsys *sbp; ! 284: register MOUNT *mp; ! 285: ! 286: if ((mp=getment(dev, 1)) == NULL) ! 287: return; ! 288: lock(mp->m_ilock); ! 289: sbp = &mp->m_super; ! 290: sbp->s_fmod = 1; ! 291: if (sbp->s_ninode < NICINOD) ! 292: sbp->s_inode[sbp->s_ninode++] = ino; ! 293: sbp->s_tinode++; ! 294: unlock(mp->m_ilock); ! 295: } ! 296: ! 297: /* ! 298: * Free all blocks in the indirect block `b' on the device `dev'. ! 299: * `l' is the level of indirection. ! 300: */ ! 301: indfree(dev, b, l) ! 302: dev_t dev; ! 303: daddr_t b; ! 304: register unsigned l; ! 305: { ! 306: register int i; ! 307: register BUF *bp; ! 308: daddr_t * dp; ! 309: daddr_t b1; ! 310: ! 311: if (b == 0) ! 312: return; ! 313: if (l-->0 && (bp=bread(dev, b, 1))!=NULL) { ! 314: i = NBN; ! 315: while (i-- > 0) { ! 316: dp = FP_OFF(bp->b_faddr); ! 317: ! 318: if ((b1 = dp[i]) == 0) ! 319: continue; ! 320: candaddr(b1); ! 321: if (l == 0) ! 322: bfree(dev, b1); ! 323: else ! 324: indfree(dev, b1, l); ! 325: } ! 326: brelease(bp); ! 327: } ! 328: bfree(dev, b); ! 329: } ! 330: ! 331: /* ! 332: * Allocate a block from the filesystem mounted of device `dev'. ! 333: */ ! 334: daddr_t ! 335: balloc(dev) ! 336: dev_t dev; ! 337: { ! 338: register struct filsys *sbp; ! 339: register struct fblk *fbp; ! 340: register daddr_t b; ! 341: register BUF *bp; ! 342: register MOUNT *mp; ! 343: ! 344: if ((mp=getment(dev, 1)) == NULL) ! 345: return (0); ! 346: lock(mp->m_flock); ! 347: sbp = &mp->m_super; ! 348: if (sbp->s_nfree == 0) { ! 349: enospc: ! 350: sbp->s_nfree = 0; ! 351: devmsg(dev, "Out of space"); ! 352: u.u_error = ENOSPC; ! 353: b = 0; ! 354: } else { ! 355: sbp->s_fmod = 1; ! 356: if ((b=sbp->s_free[--sbp->s_nfree]) == 0) ! 357: goto enospc; ! 358: if (sbp->s_nfree == 0) { ! 359: if (b >= sbp->s_fsize ! 360: || b < sbp->s_isize ! 361: || (bp = bread(dev, b, 1)) == NULL) { ! 362: ebadflist: ! 363: devmsg(dev, "Bad free list"); ! 364: goto enospc; ! 365: } ! 366: fbp = FP_OFF(bp->b_faddr); ! 367: sbp->s_nfree = fbp->df_nfree; ! 368: canshort(sbp->s_nfree); ! 369: if ((unsigned)sbp->s_nfree > NICFREE) ! 370: goto ebadflist; ! 371: kkcopy(fbp->df_free, sbp->s_free, sizeof(sbp->s_free)); ! 372: canndaddr(sbp->s_free, sbp->s_nfree); ! 373: brelease(bp); ! 374: } ! 375: --sbp->s_tfree; ! 376: if (b >= sbp->s_fsize || b < sbp->s_isize) ! 377: goto ebadflist; ! 378: } ! 379: unlock(mp->m_flock); ! 380: return (b); ! 381: } ! 382: ! 383: /* ! 384: * Free the block `b' on the device `dev'. ! 385: */ ! 386: bfree(dev, b) ! 387: dev_t dev; ! 388: daddr_t b; ! 389: { ! 390: register struct filsys *sbp; ! 391: register struct fblk *fbp; ! 392: register BUF *bp; ! 393: register MOUNT *mp; ! 394: ! 395: if ((mp=getment(dev, 1)) == NULL) ! 396: return; ! 397: sbp = &mp->m_super; ! 398: if (b>=sbp->s_fsize || b<sbp->s_isize) { ! 399: devmsg(dev, "Bad block %u (free)", (unsigned)b); ! 400: return; ! 401: } ! 402: lock(mp->m_flock); ! 403: if (sbp->s_nfree == 0 || sbp->s_nfree == NICFREE) { ! 404: bp = bclaim(dev, b); ! 405: fbp = FP_OFF(bp->b_faddr); ! 406: kclear(fbp, BSIZE); ! 407: fbp->df_nfree = sbp->s_nfree; ! 408: canshort(fbp->df_nfree); ! 409: kkcopy(sbp->s_free, fbp->df_free, sizeof(fbp->df_free)); ! 410: canndaddr(fbp->df_free, sbp->s_nfree); ! 411: bp->b_flag |= BFMOD; ! 412: brelease(bp); ! 413: sbp->s_nfree = 0; ! 414: } ! 415: sbp->s_free[sbp->s_nfree++] = b; ! 416: sbp->s_tfree++; ! 417: sbp->s_fmod = 1; ! 418: unlock(mp->m_flock); ! 419: } ! 420: ! 421: /* ! 422: * Determine if the given block is bad. ! 423: */ ! 424: bad(dev, b) ! 425: dev_t dev; ! 426: daddr_t b; ! 427: { ! 428: register INODE *ip; ! 429: register BUF *bp; ! 430: register int i; ! 431: register int m; ! 432: register int n; ! 433: daddr_t l; ! 434: ! 435: if ((ip=iattach(dev, 1)) == NULL) ! 436: panic("bad()"); ! 437: n = blockn(ip->i_size); ! 438: if ((m=n) > ND) ! 439: m = ND; ! 440: for (i=0; i<m; i++) { ! 441: --n; ! 442: if (b == ip->i_a.i_addr[i]) { ! 443: idetach(ip); ! 444: return (1); ! 445: } ! 446: } ! 447: l = ip->i_a.i_addr[ND]; ! 448: idetach(ip); ! 449: if (n == 0) ! 450: return (0); ! 451: if ((bp=bread(dev, l, 1)) == NULL) ! 452: return (0); ! 453: if ((m=n) > NBN) ! 454: m = NBN; ! 455: for (i=0; i<m; i++) { ! 456: l = ((daddr_t *)bp)[i]; ! 457: candaddr(l); ! 458: if (b == l) { ! 459: brelease(bp); ! 460: return (1); ! 461: } ! 462: } ! 463: brelease(bp); ! 464: return (0); ! 465: } ! 466: ! 467: /* ! 468: * Canonize `n' disk addresses. ! 469: */ ! 470: canndaddr(dp, n) ! 471: register daddr_t *dp; ! 472: register int n; ! 473: { ! 474: while (n--) { ! 475: candaddr(*dp); ! 476: dp++; ! 477: } ! 478: } ! 479: ! 480: /* ! 481: * Write out an accounting record. ! 482: */ ! 483: setacct() ! 484: { ! 485: register PROC *pp; ! 486: struct acct acct; ! 487: IO acctio; ! 488: ! 489: if (acctip == NULL) ! 490: return; ! 491: pp = SELF; ! 492: kkcopy(u.u_comm, acct.ac_comm, 10); ! 493: acct.ac_utime = ltoc(pp->p_utime); ! 494: acct.ac_stime = ltoc(pp->p_stime); ! 495: acct.ac_etime = ltoc(timer.t_time - u.u_btime); ! 496: acct.ac_btime = u.u_btime; ! 497: acct.ac_uid = u.u_uid; ! 498: acct.ac_gid = u.u_gid; ! 499: acct.ac_mem = 0; ! 500: acct.ac_io = ltoc(u.u_block); ! 501: acct.ac_tty = pp->p_ttdev; ! 502: acct.ac_flag = u.u_flag; ! 503: ilock(acctip); ! 504: acctio.io_seek = acctip->i_size; ! 505: acctio.io_ioc = sizeof (acct); ! 506: acctio.io_base = &acct; ! 507: acctio.io_seg = IOSYS; ! 508: acctio.io_flag = 0; ! 509: iwrite(acctip, &acctio); ! 510: iunlock(acctip); ! 511: u.u_error = 0; ! 512: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.