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

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

unix.superglobalmegacorp.com

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