Annotation of coherent/d/286_KERNEL/USRSRC/coh/fs2.c, revision 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.