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