Annotation of coherent/d/286_KERNEL/USRSRC/coh/fs2.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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