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