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