|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.