Annotation of coherent/d/PS2_KERNEL/coh.286/fs2.c, revision 1.1

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

unix.superglobalmegacorp.com

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