Annotation of coherent/b/kernel/coh.386/fs2.c, revision 1.1

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

unix.superglobalmegacorp.com

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