Annotation of coherent/b/STREAMS/coh.386/fs2.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.