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

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

unix.superglobalmegacorp.com

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