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