Annotation of coherent/d/PS2_KERNEL/coh.386/fs2.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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