Annotation of coherent/b/STREAMS/coh.386/fs2.c, revision 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.