Annotation of coherent/b/kernel/coh.386/fs3.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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