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

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

unix.superglobalmegacorp.com

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