Annotation of coherent/d/kernel/USRSRC/coh/fs3.c, revision 1.1

1.1     ! root        1: /* $Header: /newbits/kernel/USRSRC/coh/RCS/fs3.c,v 1.4 91/07/24 07:51: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 (I/O).
        !            18:  *
        !            19:  * $Log:       fs3.c,v $
        !            20:  * Revision 1.4  91/07/24  07:51:06  bin
        !            21:  * update prov by hal
        !            22:  * 
        !            23:  * 
        !            24:  * Revision 1.1        88/03/24  16:13:54      src
        !            25:  * Initial revision
        !            26:  * 
        !            27:  * 87/11/25    Allan Cornish           /usr/src/sys/coh/fs3.c
        !            28:  * vaddr_t bp->b_vaddr --> faddr_t bp->b_faddr.
        !            29:  *
        !            30:  * 86/02/01    Allan Cornish
        !            31:  * Added code to fwrite() to avoid needless writing of pipe blocks.
        !            32:  * Throughput on 6 Mhz AT rose from 30 Kbytes/sec to 79 Kbytes/sec.
        !            33:  */
        !            34: #include <sys/coherent.h>
        !            35: #include <sys/buf.h>
        !            36: #include <canon.h>
        !            37: #include <sys/con.h>
        !            38: #include <errno.h>
        !            39: #include <sys/filsys.h>
        !            40: #include <sys/mount.h>
        !            41: #include <sys/io.h>
        !            42: #include <sys/ino.h>
        !            43: #include <sys/inode.h>
        !            44: #include <sys/uproc.h>
        !            45: #include <sys/stat.h>
        !            46: 
        !            47: /*
        !            48:  * Given an inode, open it.
        !            49:  */
        !            50: iopen(ip, mode)
        !            51: register INODE *ip;
        !            52: {
        !            53:        register int type;
        !            54: 
        !            55:        type = ip->i_mode & IFMT;
        !            56:        switch (type) {
        !            57:        case IFCHR:
        !            58:        case IFBLK:
        !            59:                iunlock(ip);
        !            60:                dopen(ip->i_a.i_rdev, mode, type==IFCHR ? DFCHR : DFBLK);
        !            61:                ilock(ip);
        !            62:                break;
        !            63:        case IFDIR:
        !            64:                if ((mode&IPW) != 0) {
        !            65:                        if (super() == 0)
        !            66:                                return;
        !            67:                        if (mode == IPW) {
        !            68:                                u.u_error = EISDIR;
        !            69:                                return;
        !            70:                        }
        !            71:                }
        !            72:                break;
        !            73:        case IFPIPE:
        !            74:                popen(ip, mode);
        !            75:                break;
        !            76:        }
        !            77: }
        !            78: 
        !            79: /*
        !            80:  * Given an inode, close it.
        !            81:  */
        !            82: iclose(ip)
        !            83: register INODE *ip;
        !            84: {
        !            85:        ilock(ip);
        !            86:        switch (ip->i_mode&IFMT) {
        !            87:        case IFBLK:
        !            88:                bflush(ip->i_a.i_rdev);
        !            89:        case IFCHR:
        !            90:                iunlock(ip);
        !            91:                dclose(ip->i_a.i_rdev);
        !            92:                ilock(ip);
        !            93:                break;
        !            94:        case IFPIPE:
        !            95:                pclose(ip);
        !            96:                break;
        !            97:        }
        !            98:        idetach(ip);
        !            99: }
        !           100: 
        !           101: /*
        !           102:  * Read from a file described by an inode and an io strucuture.
        !           103:  */
        !           104: iread(ip, iop)
        !           105: register INODE *ip;
        !           106: register IO *iop;
        !           107: {
        !           108:        if (iop->io_ioc == 0)
        !           109:                return;
        !           110:        switch (ip->i_mode&IFMT) {
        !           111:        case IFCHR:
        !           112:                dread(ip->i_a.i_rdev, iop);
        !           113:                break;
        !           114:        case IFBLK:
        !           115:        case IFREG:
        !           116:        case IFDIR:
        !           117:                fread(ip, iop);
        !           118:                break;
        !           119:        case IFPIPE:
        !           120:                pread(ip, iop);
        !           121:                break;
        !           122:        default:
        !           123:                u.u_error = ENXIO;
        !           124:                break;
        !           125:        }
        !           126: }
        !           127: 
        !           128: /*
        !           129:  * Write to a file described by an inode and io structure.
        !           130:  */
        !           131: iwrite(ip, iop)
        !           132: register INODE *ip;
        !           133: register IO *iop;
        !           134: {
        !           135:        imod(ip);       /* write - mtime */
        !           136:        icrt(ip);       /* write - ctime */
        !           137:        if (iop->io_ioc == 0)
        !           138:                return;
        !           139:        switch (ip->i_mode&IFMT) {
        !           140:        case IFCHR:
        !           141:                dwrite(ip->i_a.i_rdev, iop);
        !           142:                break;
        !           143:        case IFBLK:
        !           144:                fwrite(ip, iop);
        !           145:                break;
        !           146:        case IFREG:
        !           147:        case IFDIR:
        !           148:                if (getment(ip->i_dev, 1) == NULL)
        !           149:                        return;
        !           150:                fwrite(ip, iop);
        !           151:                break;
        !           152:        case IFPIPE:
        !           153:                pwrite(ip, iop);
        !           154:                break;
        !           155:        default:
        !           156:                u.u_error = ENXIO;
        !           157:                break;
        !           158:        }
        !           159: }
        !           160: 
        !           161: /*
        !           162:  * Read from a regular or block special file.
        !           163:  */
        !           164: fread(ip, iop)
        !           165: INODE *ip;
        !           166: register IO *iop;
        !           167: {
        !           168: #ifdef TINY
        !           169:        register unsigned n;
        !           170:        register fsize_t res;
        !           171:        register unsigned off;
        !           172:        register daddr_t lbn;
        !           173:        register BUF *bp;
        !           174:        register int blk;
        !           175: 
        !           176:        lbn = blockn(iop->io_seek);
        !           177:        off = blocko(iop->io_seek);
        !           178:        blk = (ip->i_mode&IFMT) == IFBLK;
        !           179:        res = ip->i_size - iop->io_seek;
        !           180:        if (blk!=0 || res>iop->io_ioc)
        !           181:                res = iop->io_ioc;
        !           182:        while (res > 0) {
        !           183:                bp = blk ? bread(ip->i_a.i_rdev, lbn, 1) : vread(ip, lbn);
        !           184:                if (bp == NULL)
        !           185:                        return;
        !           186:                n = BSIZE - off;
        !           187:                if (n > res)
        !           188:                        n = res;
        !           189:                iowrite(iop, FP_OFF(bp->b_faddr)+off, n);
        !           190:                brelease(bp);
        !           191:                if (u.u_error)
        !           192:                        return;
        !           193:                lbn++;
        !           194:                off = 0;
        !           195:                res -= n;
        !           196:        }
        !           197: /*
        !           198:  * Start of daring read ahead code.
        !           199:  * Altered to not read ahead on block devices
        !           200:  * due to 20% time penalty incurred for such.
        !           201:  */
        !           202: #if 0
        !           203:        if ( ! blk) {
        !           204:                lbn = vmap(ip, lbn);
        !           205:                if (lbn > 0)
        !           206:                        bread(ip->i_dev, lbn, 0);
        !           207:        }
        !           208: #endif
        !           209: /*
        !           210:  * End of daring read ahead code.
        !           211:  */
        !           212: #else
        !           213:        register unsigned n;
        !           214:        register unsigned i;
        !           215:        register fsize_t res;
        !           216:        register unsigned off;
        !           217:        register dev_t dev;
        !           218:        register daddr_t lbn;
        !           219:        register daddr_t pbn;
        !           220:        register daddr_t abn;
        !           221:        register daddr_t zbn;
        !           222:        register BUF *bp;
        !           223:        register int blk;
        !           224:        daddr_t list[NEXREAD];
        !           225: 
        !           226:        if ((ip->i_mode&IFMT) == IFBLK) {
        !           227:                blk = 1;
        !           228:                dev = ip->i_a.i_rdev;
        !           229:        } else {
        !           230:                blk = 0;
        !           231:                dev = ip->i_dev;
        !           232:        }
        !           233:        abn = 0;
        !           234:        zbn = 0;
        !           235:        lbn = blockn(iop->io_seek);
        !           236:        off = blocko(iop->io_seek);
        !           237:        res = ip->i_size - iop->io_seek;
        !           238:        if (blk!=0 || res>iop->io_ioc)
        !           239:                res = iop->io_ioc;
        !           240:        if (res <= 0)
        !           241:                return;
        !           242:        if (res+off <= BSIZE) {
        !           243:                bp = blk ? bread(dev, lbn, 1) : vread(ip, lbn);
        !           244:                if (bp == NULL)
        !           245:                        return;
        !           246:                iowrite(iop, FP_OFF(bp->b_faddr)+off, (unsigned)res);
        !           247:                brelease(bp);
        !           248:                return;
        !           249:        }
        !           250:        while (res > 0) {
        !           251:                if (lbn >= zbn) {
        !           252:                        if ((n=blockn(res+BSIZE-1)) > NEXREAD)
        !           253:                                n = NEXREAD;
        !           254:                        if (n <= 0)
        !           255:                                n = 1;
        !           256:                        abn = lbn;
        !           257:                        for (i=0, zbn=lbn; i<n; i++, zbn++) {
        !           258:                                if (blk != 0)
        !           259:                                        pbn = zbn;
        !           260:                                else {
        !           261:                                        if ((pbn=vmap(ip, zbn)) < 0)
        !           262:                                                return;
        !           263:                                        if (pbn == 0) {
        !           264:                                                list[i] = -1;
        !           265:                                                continue;
        !           266:                                        }
        !           267:                                }
        !           268:                                list[i] = pbn;
        !           269:                                bread(dev, pbn, 0);
        !           270:                        }
        !           271:                }
        !           272:                if ((pbn=list[lbn-abn]) < 0) {
        !           273:                        bp = bclaim(NODEV, (daddr_t)0);
        !           274:                        kclear(FP_OFF(bp->b_faddr), BSIZE);
        !           275:                } else {
        !           276:                        if ((bp=bread(dev, pbn, 1)) == NULL)
        !           277:                                return;
        !           278:                }
        !           279:                n = BSIZE - off;
        !           280:                n = res>n ? n : res;
        !           281:                iowrite(iop, FP_OFF(bp->b_faddr)+off, n);
        !           282:                brelease(bp);
        !           283:                if (u.u_error)
        !           284:                        return;
        !           285:                lbn++;
        !           286:                off = 0;
        !           287:                res -= n;
        !           288:        }
        !           289: #endif
        !           290: }
        !           291: 
        !           292: /*
        !           293:  * Write to a regular or block special file.
        !           294:  */
        !           295: fwrite(ip, iop)
        !           296: INODE *ip;
        !           297: register IO *iop;
        !           298: {
        !           299:        register unsigned n;
        !           300:        register unsigned off;
        !           301:        register daddr_t lbn;
        !           302:        register BUF *bp;
        !           303:        register int blk;
        !           304:        register int com;
        !           305: 
        !           306:        lbn = blockn(iop->io_seek);
        !           307:        off = blocko(iop->io_seek);
        !           308:        blk = (ip->i_mode&IFMT) == IFBLK;
        !           309:        while (iop->io_ioc > 0) {
        !           310:                n = BSIZE - off;
        !           311:                n = iop->io_ioc>n ? n : iop->io_ioc;
        !           312:                com = off==0 && n==BSIZE;
        !           313:                if (blk == 0)
        !           314:                        bp = aread(ip, lbn, com);
        !           315:                else {
        !           316:                        if (com)
        !           317:                                bp = bclaim(ip->i_a.i_rdev, lbn);
        !           318:                        else
        !           319:                                bp = bread(ip->i_a.i_rdev, lbn, 1);
        !           320:                }
        !           321:                if (bp == NULL)
        !           322:                        return;
        !           323:                ioread(iop, FP_OFF(bp->b_faddr)+off, n);
        !           324:                bp->b_flag |= BFMOD;
        !           325:                if (com && ((ip->i_mode&IFMT) != IFPIPE) )
        !           326:                        bwrite(bp, 0);
        !           327:                else
        !           328:                        brelease(bp);
        !           329:                if (u.u_error)
        !           330:                        return;
        !           331:                lbn++;
        !           332:                off = 0;
        !           333:                if ((iop->io_seek+=n) > ip->i_size)
        !           334:                        if (blk == 0)
        !           335:                                ip->i_size = iop->io_seek;
        !           336:        }
        !           337: }
        !           338: 
        !           339: /*
        !           340:  * Given an inode pointer, read the requested virtual block and return
        !           341:  * a buffer with the data.
        !           342:  */
        !           343: BUF *
        !           344: vread(ip, lb)
        !           345: register INODE *ip;
        !           346: daddr_t lb;
        !           347: {
        !           348:        register daddr_t pb;
        !           349:        register BUF *bp;
        !           350: 
        !           351:        if ((pb=vmap(ip, lb)) < 0)
        !           352:                return (NULL);
        !           353:        if (pb != 0)
        !           354:                return (bread(ip->i_dev, pb, 1));
        !           355:        bp = bclaim(NODEV, (daddr_t)0);
        !           356:        kclear(FP_OFF(bp->b_faddr), BSIZE);
        !           357:        return (bp);
        !           358: }
        !           359: 
        !           360: /*
        !           361:  * Convert the given virtual block to a physical block for the given inode.
        !           362:  * If the block does not map onto a physical block because the file is sparse
        !           363:  * but it does exist, 0 is returned.  If an error is encountered, -1 is
        !           364:  * returned.
        !           365:  */
        !           366: daddr_t
        !           367: vmap(ip, lb)
        !           368: register INODE *ip;
        !           369: daddr_t lb;
        !           370: {
        !           371:        register BUF *bp;
        !           372:        register int *lp;
        !           373:        daddr_t * dp;
        !           374:        daddr_t pb;
        !           375:        int list[1+NI];
        !           376: 
        !           377:        if ((lp=lmap(lb, list)) == NULL)
        !           378:                return (-1);
        !           379:        pb = ip->i_a.i_addr[*--lp];
        !           380:        for (;;) {
        !           381:                if (pb==0 || lp==list)
        !           382:                        return (pb);
        !           383:                if ((bp=bread(ip->i_dev, pb, 1)) == NULL)
        !           384:                        return (0);
        !           385:                dp = FP_OFF(bp->b_faddr);
        !           386:                pb = dp[*--lp];
        !           387:                brelease(bp);
        !           388:                candaddr(pb);
        !           389:        }
        !           390: }
        !           391: 
        !           392: /*
        !           393:  * Given an inode pointer, read the requested virtual block and return a
        !           394:  * buffer with the data.  In sparse files, the necessary blocks are allocated.
        !           395:  * If the flag, `fflag' is set, the final buffer is just claimed rather than
        !           396:  * read as we are going to change it's contents completely.
        !           397:  */
        !           398: BUF *
        !           399: aread(ip, lb, fflag)
        !           400: register INODE *ip;
        !           401: daddr_t lb;
        !           402: {
        !           403:        register BUF *bp;
        !           404:        register int *lp;
        !           405:        register dev_t dev;
        !           406:        register int l;
        !           407:        register int aflag;
        !           408:        register int lflag;
        !           409:        daddr_t * dp;
        !           410:        daddr_t pb;
        !           411:        int list[1+NI];
        !           412: 
        !           413:        if ((lp=lmap(lb, list)) == NULL)
        !           414:                return (NULL);
        !           415:        aflag = 0;
        !           416:        dev = ip->i_dev;
        !           417:        pb = ip->i_a.i_addr[l=*--lp];
        !           418:        if (pb == 0) {
        !           419:                aflag = 1;
        !           420:                if ((pb=balloc(dev)) == 0)
        !           421:                        return (NULL);
        !           422:                ip->i_a.i_addr[l] = pb;
        !           423:        }
        !           424:        for (;;) {
        !           425:                lflag = lp==list;
        !           426:                if (aflag==0  &&  (fflag==0 || lflag==0)) {
        !           427:                        if ((bp=bread(dev, pb, 1)) == NULL)
        !           428:                                return (NULL);
        !           429:                } else {
        !           430:                        bp = bclaim(dev, pb);
        !           431:                        kclear(FP_OFF(bp->b_faddr), BSIZE);
        !           432:                        bp->b_flag |= BFMOD;
        !           433:                }
        !           434:                if (lflag)
        !           435:                        return (bp);
        !           436: 
        !           437:                aflag = 0;
        !           438:                dp = FP_OFF(bp->b_faddr);
        !           439:                pb = dp[l=*--lp];
        !           440:                candaddr(pb);
        !           441:                if (pb == 0) {
        !           442:                        aflag = 1;
        !           443:                        if ((pb=balloc(dev)) == 0) {
        !           444:                                brelease(bp);
        !           445:                                return (NULL);
        !           446:                        }
        !           447:                        dp[l] = pb;
        !           448:                        candaddr( dp[l] );
        !           449:                        bp->b_flag |= BFMOD;
        !           450:                }
        !           451:                brelease(bp);
        !           452:        }
        !           453: }
        !           454: 
        !           455: /*
        !           456:  * Given a block number, `b', store the offsets for the indirect blocks
        !           457:  * backwards in the array, `lp', and return a pointer just after the
        !           458:  * position where the first offset is stored.
        !           459:  */
        !           460: int *
        !           461: lmap(b, lp)
        !           462: register daddr_t b;
        !           463: register int *lp;
        !           464: {
        !           465:        register int n;
        !           466: 
        !           467:        if (b < ND) {
        !           468:                *lp++ = b;
        !           469:                return (lp);
        !           470:        }
        !           471:        b -= ND;
        !           472:        n = NI;
        !           473:        do {
        !           474:                if (n-- == 0) {
        !           475:                        u.u_error = EFBIG;
        !           476:                        return (NULL);
        !           477:                }
        !           478:                *lp = nbnrem(b);
        !           479:                ++lp;
        !           480:                b = nbndiv(b);
        !           481:        } while (b--);
        !           482:        *lp++ = ND+NI-1-n;
        !           483:        return (lp);
        !           484: }

unix.superglobalmegacorp.com

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