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