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