|
|
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.