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