|
|
1.1 ! root 1: /* $Header: /src386/STREAMS/coh.386/RCS/fs2.c,v 2.3 93/08/09 13:35:33 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 2.3 93/08/09 13:35:33 bin ! 21: * Kernel 82 changes ! 22: * ! 23: * Revision 2.2 93/07/26 15:19:24 nigel ! 24: * Nigel's R80 ! 25: * ! 26: * Revision 2.2 93/07/26 14:28:32 nigel ! 27: * Nigel's R80 ! 28: * ! 29: * Revision 1.5 93/04/14 10:06:31 root ! 30: * r75 ! 31: * ! 32: * Revision 1.2 92/01/06 11:59:27 hal ! 33: * Compile with cc.mwc. ! 34: * ! 35: * Revision 1.1 88/03/24 16:13:51 src ! 36: * Initial revision ! 37: * ! 38: * 87/04/29 Allan Cornish /usr/src/sys/coh/fs2.c ! 39: * Fsminit panic messages now specify the root major and minor device. ! 40: * ! 41: * 86/11/19 Allan Cornish /usr/src/sys/coh/fs2.c ! 42: * setacct() initializes the (new) (IO).io_flag field to 0. ! 43: * ! 44: * 85/08/08 Allan Cornish ! 45: * ialloc() erroneously did a brelease(NULL) if bclaim() returned NULL. ! 46: * also, sbp->s_fmod was set BEFORE the in-core inode table was updated. ! 47: * This created a critical race with msync() (called by sync system call). ! 48: * ! 49: * 85/04/17 Allan Cornish ! 50: * eliminated test for rootdev in msync() ! 51: */ ! 52: ! 53: #include <common/ccompat.h> ! 54: #include <sys/debug.h> ! 55: ! 56: #include <sys/coherent.h> ! 57: #include <sys/acct.h> ! 58: #include <sys/buf.h> ! 59: #include <canon.h> ! 60: #include <sys/con.h> ! 61: #include <sys/errno.h> ! 62: #include <sys/filsys.h> ! 63: #include <sys/ino.h> ! 64: #include <sys/inode.h> ! 65: #include <sys/io.h> ! 66: #include <sys/mount.h> ! 67: #include <sys/proc.h> ! 68: #include <sys/stat.h> ! 69: #include <sys/file.h> ! 70: ! 71: #define _INODE_BUSY_DUMP 1 ! 72: ! 73: /* ! 74: * Initialise filesystem. ! 75: */ ! 76: fsminit() ! 77: { ! 78: register MOUNT *mp; ! 79: INODE * ip; ! 80: ! 81: /* ! 82: * NIGEL: We begin by setting up all the inodes in the system. ! 83: */ ! 84: ! 85: for (ip = inodep + NINODE - 1 ; ip >= inodep ; ip --) { ! 86: ip->i_refc = 0; ! 87: __GATE_INIT (ip->i_gate, "inode"); ! 88: } ! 89: ! 90: ! 91: /* ! 92: * Mount the root file system. ! 93: */ ! 94: if ((mp = fsmount (rootdev, ronflag)) == NULL) ! 95: panic ("fsminit: no rootdev(%d,%d)", ! 96: major (rootdev), minor (rootdev)); ! 97: ! 98: /* ! 99: * Set system time from the super block. ! 100: */ ! 101: timer.t_time = mp->m_super.s_time; ! 102: ! 103: /* ! 104: * Access the root directory. ! 105: */ ! 106: if ((u.u_rdir = iattach (rootdev, ROOTIN)) == NULL) ! 107: panic ("fsminit: no / on rootdev(%d,%d)", ! 108: major (rootdev), minor (rootdev)); ! 109: ! 110: /* ! 111: * Record current directory. ! 112: */ ! 113: u.u_cdir = u.u_rdir; ! 114: u.u_cdir->i_refc++; ! 115: iunlock (u.u_rdir); ! 116: } ! 117: ! 118: ! 119: /* ! 120: * Mount the given device. ! 121: */ ! 122: MOUNT * ! 123: fsmount(dev, f) ! 124: register dev_t dev; ! 125: { ! 126: register MOUNT *mp; ! 127: register BUF *bp; ! 128: ! 129: if ((mp = kalloc (sizeof (MOUNT))) == NULL) { ! 130: printf ("fsmount(%x,%x): kalloc failed ", dev, f); ! 131: return NULL; ! 132: } ! 133: dopen (dev, (f ? IPR : IPR | IPW), DFBLK); ! 134: if (u.u_error) { ! 135: printf("fsmount(%x,%x): dopen failed ", dev, f); ! 136: kfree (mp); ! 137: return NULL; ! 138: } ! 139: if ((bp = bread (dev, (daddr_t) SUPERI, BUF_SYNC)) == NULL) { ! 140: dclose (dev, (f ? IPR : IPR | IPW), DFBLK); /* NIGEL */ ! 141: kfree (mp); ! 142: return NULL; ! 143: } ! 144: memcpy (& mp->m_super, bp->b_vaddr, sizeof (mp->m_super)); ! 145: brelease (bp); ! 146: cansuper (& mp->m_super); ! 147: ! 148: mp->m_ip = NULL; ! 149: mp->m_dev = dev; ! 150: mp->m_flag = f; ! 151: mp->m_super.s_fmod = 0; ! 152: mp->m_next = mountp; ! 153: ! 154: __GATE_INIT (mp->m_ilock, "mount ilock"); ! 155: __GATE_INIT (mp->m_flock, "mount flock"); ! 156: ! 157: mountp = mp; ! 158: return mp; ! 159: } ! 160: ! 161: ! 162: /* ! 163: * Canonize a super block. ! 164: */ ! 165: cansuper(fsp) ! 166: register struct filsys *fsp; ! 167: { ! 168: register int i; ! 169: ! 170: canint (fsp->s_isize); ! 171: candaddr (fsp->s_fsize); ! 172: canshort (fsp->s_nfree); ! 173: for (i = 0 ; i < NICFREE ; i ++) ! 174: candaddr (fsp->s_free [i]); ! 175: canshort (fsp->s_ninode); ! 176: for (i = 0 ; i < NICINOD ; i ++) ! 177: canino (fsp->s_inode [i]); ! 178: cantime (fsp->s_time); ! 179: candaddr (fsp->s_tfree); ! 180: canino (fsp->s_tinode); ! 181: canshort (fsp->s_m); ! 182: canshort (fsp->s_n); ! 183: canlong (fsp->s_unique); ! 184: } ! 185: ! 186: /* ! 187: * Given a pointer to a mount entry, write out all inodes on that device. ! 188: */ ! 189: msync(mp) ! 190: register MOUNT *mp; ! 191: { ! 192: register struct filsys *sbp; ! 193: register BUF *bp; ! 194: ! 195: if ((mp->m_flag & MFRON) != 0) ! 196: return; ! 197: isync (mp->m_dev); ! 198: sbp = & mp->m_super; ! 199: if (sbp->s_fmod == 0) ! 200: return; ! 201: bp = bclaim (mp->m_dev, (daddr_t) SUPERI, BUF_SYNC); ! 202: sbp->s_time = timer.t_time; ! 203: sbp->s_fmod = 0; ! 204: memcpy (bp->b_vaddr, sbp, sizeof (* sbp)); ! 205: cansuper (bp->b_vaddr); ! 206: bwrite (bp, 1); ! 207: brelease (bp); ! 208: } ! 209: ! 210: /* ! 211: * Return the mount entry for the given device. If `f' is not set ! 212: * and the device is read only, don't set the error status. ! 213: */ ! 214: MOUNT * ! 215: getment(dev, f) ! 216: register dev_t dev; ! 217: { ! 218: register MOUNT *mp; ! 219: ! 220: for (mp = mountp ; mp != NULL ; mp = mp->m_next) { ! 221: if (mp->m_dev != dev) ! 222: continue; ! 223: if ((mp->m_flag & MFRON) != 0) { ! 224: if (f != 0) ! 225: u.u_error = EROFS; ! 226: return NULL; ! 227: } ! 228: return mp; ! 229: } ! 230: panic ("getment: dev=0x%x", dev); ! 231: } ! 232: ! 233: /* ! 234: * Allocate a new inode with the given mode. The returned inode is locked. ! 235: */ ! 236: INODE * ! 237: ialloc(dev, mode) ! 238: dev_t dev; ! 239: unsigned mode; ! 240: { ! 241: register struct dinode *dip; ! 242: register struct filsys *sbp; ! 243: register ino_t *inop; ! 244: register ino_t ino; ! 245: register BUF *bp; ! 246: register daddr_t b; ! 247: register struct dinode *dipe; ! 248: register ino_t *inope; ! 249: register MOUNT *mp; ! 250: register INODE *ip; ! 251: #if _INODE_BUSY_DUMP ! 252: int eninode, etinode; ! 253: int lninode, ltinode; ! 254: int xninode, xtinode; ! 255: #endif ! 256: ! 257: if ((mp = getment (dev, 1)) == NULL) ! 258: return NULL; ! 259: sbp = & mp->m_super; ! 260: ! 261: #if _INODE_BUSY_DUMP ! 262: eninode = sbp->s_ninode; ! 263: etinode = sbp->s_tinode; ! 264: #endif ! 265: ! 266: for (;;) { ! 267: lock (mp->m_ilock); ! 268: ! 269: #if _INODE_BUSY_DUMP ! 270: lninode = sbp->s_ninode; ! 271: ltinode = sbp->s_tinode; ! 272: #endif ! 273: ! 274: if (sbp->s_ninode == 0) { ! 275: isync (dev); ! 276: ino = 1; ! 277: inop = sbp->s_inode; ! 278: inope = & sbp->s_inode [NICINOD]; ! 279: for (b = INODEI ; b < sbp->s_isize ; b ++) { ! 280: if (bad (dev, b)) { ! 281: ino += INOPB; ! 282: continue; ! 283: } ! 284: if ((bp = bread (dev, b, BUF_SYNC)) == NULL) { ! 285: ino += INOPB; ! 286: continue; ! 287: } ! 288: dip = bp->b_vaddr; ! 289: dipe = & dip [INOPB]; ! 290: for (; dip < dipe ; dip ++, ino ++) { ! 291: if (dip->di_mode != 0) ! 292: continue; ! 293: if (inop >= inope) ! 294: break; ! 295: * inop ++ = ino; ! 296: } ! 297: brelease (bp); ! 298: if (inop >= inope) ! 299: break; ! 300: } ! 301: sbp->s_ninode = inop - sbp->s_inode; ! 302: if (sbp->s_ninode == 0) { ! 303: sbp->s_tinode = 0; ! 304: unlock (mp->m_ilock); ! 305: devmsg (dev, "Out of inodes"); ! 306: u.u_error = ENOSPC; ! 307: return NULL; ! 308: } ! 309: } ! 310: ! 311: #if _INODE_BUSY_DUMP ! 312: xninode = sbp->s_ninode; ! 313: xtinode = sbp->s_tinode; ! 314: #endif ! 315: ! 316: ino = sbp->s_inode [-- sbp->s_ninode]; ! 317: -- sbp->s_tinode; ! 318: sbp->s_fmod = 1; ! 319: unlock (mp->m_ilock); ! 320: if ((ip = iattach(dev, ino)) != NULL) { ! 321: if (ip->i_mode != 0) { ! 322: devmsg(dev, "Inode %u busy", ino); ! 323: ! 324: #if _INODE_BUSY_DUMP ! 325: printf("%x %x rf=%x fl=%x md=%x nl=%x en=%x et=%x ln=%x lt=%x xn=%x xt=%x n=%x t=%x\n", ! 326: mode, ino, ip->i_refc, ip->i_flag, ip->i_mode, ip->i_nlink, ! 327: eninode, etinode, lninode, ltinode, xninode, xtinode, ! 328: sbp->s_ninode, sbp->s_tinode); ! 329: #endif ! 330: ! 331: idetach (ip); ! 332: lock (mp->m_ilock); ! 333: ++ sbp->s_tinode; ! 334: sbp->s_fmod = 1; ! 335: unlock (mp->m_ilock); ! 336: continue; ! 337: } ! 338: ip->i_flag = 0; ! 339: ip->i_mode = mode; ! 340: ip->i_nlink = 0; ! 341: ip->i_uid = u.u_uid; ! 342: ip->i_gid = u.u_gid; ! 343: } ! 344: return ip; ! 345: } ! 346: } ! 347: ! 348: /* ! 349: * Free the inode `ino' on device `dev'. ! 350: */ ! 351: ifree(dev, ino) ! 352: dev_t dev; ! 353: ino_t ino; ! 354: { ! 355: register struct filsys *sbp; ! 356: register MOUNT *mp; ! 357: ! 358: if ((mp = getment(dev, 1)) == NULL) ! 359: return; ! 360: lock (mp->m_ilock); ! 361: sbp = & mp->m_super; ! 362: sbp->s_fmod = 1; ! 363: if (sbp->s_ninode < NICINOD) ! 364: sbp->s_inode [sbp->s_ninode ++] = ino; ! 365: sbp->s_tinode ++; ! 366: unlock (mp->m_ilock); ! 367: } ! 368: ! 369: /* ! 370: * Free all blocks in the indirect block `b' on the device `dev'. ! 371: * `l' is the level of indirection. ! 372: */ ! 373: indfree(dev, b, l) ! 374: dev_t dev; ! 375: daddr_t b; ! 376: register unsigned l; ! 377: { ! 378: register int i; ! 379: register BUF *bp; ! 380: daddr_t * dp; ! 381: daddr_t b1; ! 382: ! 383: if (b == 0) ! 384: return; ! 385: if (l -- > 0 && (bp = bread (dev, b, BUF_SYNC)) != NULL) { ! 386: i = NBN; ! 387: while (i -- > 0) { ! 388: dp = bp->b_vaddr; ! 389: if ((b1 = dp [i]) == 0) ! 390: continue; ! 391: candaddr (b1); ! 392: if (l == 0) ! 393: bfree (dev, b1); ! 394: else ! 395: indfree (dev, b1, l); ! 396: } ! 397: brelease (bp); ! 398: } ! 399: bfree (dev, b); ! 400: } ! 401: ! 402: /* ! 403: * Experimental routine to read free block lists blocks (ahead of time, but ! 404: * if it works we'll subsume the synchronous read as well). ! 405: */ ! 406: ! 407: static BUF * ! 408: read_free_block_list (super, dev, block_no, sync_flag) ! 409: struct filsys * super; ! 410: dev_t dev; ! 411: daddr_t block_no; ! 412: int sync_flag; ! 413: { ! 414: return block_no < super->s_fsize && block_no >= super->s_isize ? ! 415: bread (dev, block_no, sync_flag) : NULL; ! 416: } ! 417: ! 418: ! 419: /* ! 420: * Allocate a block from the filesystem mounted of device `dev'. ! 421: */ ! 422: ! 423: daddr_t ! 424: balloc(dev) ! 425: dev_t dev; ! 426: { ! 427: register struct filsys *sbp; ! 428: register struct fblk *fbp; ! 429: register daddr_t b; ! 430: register BUF *bp; ! 431: register MOUNT *mp; ! 432: ! 433: if ((mp = getment(dev, 1)) == NULL) ! 434: return 0; ! 435: lock (mp->m_flock); ! 436: sbp = & mp->m_super; ! 437: if (sbp->s_nfree == 0) { ! 438: enospc: ! 439: sbp->s_nfree = 0; ! 440: devmsg (dev, "Out of space"); ! 441: u.u_error = ENOSPC; ! 442: b = 0; ! 443: } else { ! 444: sbp->s_fmod = 1; ! 445: if ((b = sbp->s_free [-- sbp->s_nfree]) == 0) ! 446: goto enospc; ! 447: if (sbp->s_nfree == 0) { ! 448: if ((bp = read_free_block_list (sbp, dev, b, ! 449: BUF_SYNC)) == NULL) { ! 450: ebadflist: ! 451: devmsg(dev, "Bad free list"); ! 452: goto enospc; ! 453: } ! 454: fbp = bp->b_vaddr; ! 455: sbp->s_nfree = fbp->df_nfree; ! 456: canshort (sbp->s_nfree); ! 457: memcpy (sbp->s_free, fbp->df_free, ! 458: sizeof (sbp->s_free)); ! 459: ! 460: if (sbp->s_nfree > NICFREE) ! 461: goto ebadflist; ! 462: brelease (bp); ! 463: ! 464: canndaddr (sbp->s_free, sbp->s_nfree); ! 465: ! 466: /* ! 467: * NIGEL: As an experiment, try reading ahead on the ! 468: * free block list. ! 469: */ ! 470: ! 471: if (sbp->s_nfree > 0) ! 472: read_free_block_list (sbp, dev, ! 473: sbp->s_free [0], ! 474: BUF_ASYNC); ! 475: } ! 476: -- sbp->s_tfree; ! 477: if (b >= sbp->s_fsize || b < sbp->s_isize) ! 478: goto ebadflist; ! 479: } ! 480: unlock (mp->m_flock); ! 481: return b; ! 482: } ! 483: ! 484: ! 485: /* ! 486: * Flag to say whether we should try and keep the free-block list sorted. ! 487: */ ! 488: ! 489: int t_sortblocks = 0; ! 490: ! 491: /* ! 492: * If we are sorting blocks, this routine can be used to keep blocks in sorted ! 493: * order. Given a fixed-size list in reverse rank order, this routine returns ! 494: * the new element if it is smaller than all others, or the smallest element ! 495: * after the new element has been inserted in position. ! 496: */ ! 497: ! 498: #if __USE_PROTO__ ! 499: static daddr_t daddr_add (daddr_t * list, int count, daddr_t newblock) ! 500: #else ! 501: static daddr_t ! 502: daddr_add (list, count, newblock) ! 503: daddr_t * list; ! 504: int count; ! 505: daddr_t newblock; ! 506: #endif ! 507: { ! 508: daddr_t * end = list + count; ! 509: ! 510: ASSERT (count >= 0); ! 511: ! 512: while (list != end) { ! 513: if (newblock < * list ++) { ! 514: daddr_t temp; ! 515: /* ! 516: * We have found the insertion point... move all the ! 517: * elements from (list - 1) to (end - 1) up, and put ! 518: * the new element in place. ! 519: */ ! 520: ! 521: temp = * -- end; ! 522: list --; ! 523: ! 524: while (list != end) { ! 525: end --; ! 526: * (end + 1) = * end; ! 527: } ! 528: * list = newblock; ! 529: return temp; ! 530: } ! 531: } ! 532: ! 533: return newblock; ! 534: } ! 535: ! 536: ! 537: /* ! 538: * Free the block `b' on the device `dev'. ! 539: */ ! 540: bfree(dev, b) ! 541: dev_t dev; ! 542: daddr_t b; ! 543: { ! 544: register struct filsys *sbp; ! 545: register struct fblk *fbp; ! 546: register BUF *bp; ! 547: register MOUNT *mp; ! 548: ! 549: if ((mp = getment (dev, 1)) == NULL) ! 550: return; ! 551: sbp = & mp->m_super; ! 552: if (b >= sbp->s_fsize || b < sbp->s_isize) { ! 553: devmsg (dev, "Bad block %u (free)", (unsigned) b); ! 554: return; ! 555: } ! 556: ! 557: /* ! 558: * NIGEL : Are we keeping things in order? If so, insert the new block ! 559: * in position (the smallest block-number is the new 'b'). Note that ! 560: * the zero-position of the free-block list never changes... this is ! 561: * an important invariant, because the block in that position is a ! 562: * link and *must* be preserved in that position so that the links get ! 563: * properly followed later on. ! 564: */ ! 565: ! 566: if (t_sortblocks && sbp->s_nfree > 0) ! 567: b = daddr_add (sbp->s_free + 1, sbp->s_nfree - 1, b); ! 568: ! 569: lock (mp->m_flock); ! 570: if (sbp->s_nfree == 0 || sbp->s_nfree == NICFREE) { ! 571: bp = bclaim (dev, b, BUF_SYNC); ! 572: fbp = bp->b_vaddr; ! 573: ! 574: /* ! 575: * NIGEL: Is there really any reason to do this? ! 576: */ ! 577: memset (bp->b_vaddr, 0, BSIZE); ! 578: ! 579: fbp->df_nfree = sbp->s_nfree; ! 580: canshort (fbp->df_nfree); ! 581: memcpy (fbp->df_free, sbp->s_free, sizeof (fbp->df_free)); ! 582: canndaddr (fbp->df_free, sbp->s_nfree); ! 583: ! 584: bp->b_flag |= BFMOD; ! 585: brelease (bp); ! 586: sbp->s_nfree = 0; ! 587: } ! 588: sbp->s_free [sbp->s_nfree ++] = b; ! 589: sbp->s_tfree ++; ! 590: sbp->s_fmod = 1; ! 591: unlock (mp->m_flock); ! 592: } ! 593: ! 594: /* ! 595: * Determine if the given block is bad. ! 596: */ ! 597: bad(dev, b) ! 598: dev_t dev; ! 599: daddr_t b; ! 600: { ! 601: register INODE *ip; ! 602: register BUF *bp; ! 603: register int i; ! 604: register int m; ! 605: register int n; ! 606: daddr_t l; ! 607: ! 608: if ((ip = iattach (dev, 1)) == NULL) ! 609: panic ("bad()"); ! 610: n = blockn (ip->i_size); ! 611: if ((m = n) > ND) ! 612: m = ND; ! 613: for (i = 0 ; i < m ; i ++) { ! 614: -- n; ! 615: if (b == ip->i_a.i_addr [i]) { ! 616: idetach (ip); ! 617: return 1; ! 618: } ! 619: } ! 620: l = ip->i_a.i_addr [ND]; ! 621: idetach (ip); ! 622: if (n == 0) ! 623: return 0; ! 624: if ((bp = bread (dev, l, BUF_SYNC)) == NULL) ! 625: return 0; ! 626: if ((m = n) > NBN) ! 627: m = NBN; ! 628: for (i = 0 ; i < m ; i ++) { ! 629: l = ((daddr_t *) bp) [i]; ! 630: candaddr (l); ! 631: if (b == l) { ! 632: brelease (bp); ! 633: return 1; ! 634: } ! 635: } ! 636: brelease (bp); ! 637: return 0; ! 638: } ! 639: ! 640: /* ! 641: * Canonize `n' disk addresses. ! 642: */ ! 643: canndaddr(dp, n) ! 644: register daddr_t *dp; ! 645: register int n; ! 646: { ! 647: while (n --) { ! 648: candaddr (* dp); ! 649: dp ++; ! 650: } ! 651: } ! 652: ! 653: /* ! 654: * Convert long to comp_t style number. ! 655: * A comp_t contains 3 bits of base-8 exponent ! 656: * and a 13-bit mantissa. Only unsigned ! 657: * numbers can be comp_t numbers. ! 658: */ ! 659: ! 660: #define MAXMANT 017777 /* 2^13-1 = largest mantissa */ ! 661: ! 662: static comp_t ! 663: ltoc(l) ! 664: long l; ! 665: { ! 666: register int exp; ! 667: ! 668: if (l < 0) ! 669: return 0; ! 670: for (exp = 0 ; l > MAXMANT ; exp ++) ! 671: l >>= 3; ! 672: return (exp << 13) | l; ! 673: } ! 674: ! 675: /* ! 676: * Write out an accounting record. ! 677: */ ! 678: setacct() ! 679: { ! 680: register PROC *pp; ! 681: struct acct acct; ! 682: IO acctio; ! 683: ! 684: if (acctip == NULL) ! 685: return; ! 686: pp = SELF; ! 687: kkcopy(u.u_comm, acct.ac_comm, 10); ! 688: acct.ac_utime = ltoc(pp->p_utime); ! 689: acct.ac_stime = ltoc(pp->p_stime); ! 690: acct.ac_etime = ltoc(timer.t_time - u.u_btime); ! 691: acct.ac_btime = u.u_btime; ! 692: acct.ac_uid = u.u_uid; ! 693: acct.ac_gid = u.u_gid; ! 694: acct.ac_mem = 0; ! 695: acct.ac_io = ltoc(u.u_block); ! 696: acct.ac_tty = pp->p_ttdev; ! 697: acct.ac_flag = u.u_flag; ! 698: ilock(acctip); ! 699: acctio.io_seek = acctip->i_size; ! 700: acctio.io_ioc = sizeof (acct); ! 701: acctio.io.vbase = &acct; ! 702: acctio.io_seg = IOSYS; ! 703: acctio.io_flag = 0; ! 704: iwrite(acctip, &acctio); ! 705: iunlock(acctip); ! 706: u.u_error = 0; ! 707: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.