Annotation of coherent/d/286_KERNEL/USRSRC/coh/fs3.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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