|
|
1.1 root 1: /*
2: * Copyright (c) 1983, 1988 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that the above copyright notice and this paragraph are
7: * duplicated in all such forms and that any documentation,
8: * advertising materials, and other materials related to such
9: * distribution and use acknowledge that the software was developed
10: * by the University of California, Berkeley. The name of the
11: * University may not be used to endorse or promote products derived
12: * from this software without specific prior written permission.
13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16: *
17: * @(#)ufs_machdep.c 7.2 (Berkeley) 6/29/88
18: */
19:
20: #include "param.h"
21: #include "systm.h"
22: #include "dir.h"
23: #include "user.h"
24: #include "buf.h"
25: #include "conf.h"
26: #include "proc.h"
27: #include "seg.h"
28: #include "vm.h"
29:
30: #include "pte.h"
31:
32: /*
33: * Machine dependent handling of the buffer cache.
34: */
35:
36: /*
37: * Expand or contract the actual memory allocated to a buffer.
38: * If no memory is available, release buffer and take error exit
39: */
40: allocbuf(tp, size)
41: register struct buf *tp;
42: int size;
43: {
44: register struct buf *bp, *ep;
45: int sizealloc, take;
46:
47: sizealloc = roundup(size, CLBYTES);
48: /*
49: * Buffer size does not change
50: */
51: if (sizealloc == tp->b_bufsize)
52: goto out;
53: /*
54: * Buffer size is shrinking.
55: * Place excess space in a buffer header taken from the
56: * BQ_EMPTY buffer list and placed on the "most free" list.
57: * If no extra buffer headers are available, leave the
58: * extra space in the present buffer.
59: */
60: if (sizealloc < tp->b_bufsize) {
61: ep = bfreelist[BQ_EMPTY].av_forw;
62: if (ep == &bfreelist[BQ_EMPTY])
63: goto out;
64: notavail(ep);
65: pagemove(tp->b_un.b_addr + sizealloc, ep->b_un.b_addr,
66: (int)tp->b_bufsize - sizealloc);
67: ep->b_bufsize = tp->b_bufsize - sizealloc;
68: tp->b_bufsize = sizealloc;
69: ep->b_flags |= B_INVAL;
70: ep->b_bcount = 0;
71: brelse(ep);
72: goto out;
73: }
74: /*
75: * More buffer space is needed. Get it out of buffers on
76: * the "most free" list, placing the empty headers on the
77: * BQ_EMPTY buffer header list.
78: */
79: while (tp->b_bufsize < sizealloc) {
80: take = sizealloc - tp->b_bufsize;
81: bp = getnewbuf();
82: if (take >= bp->b_bufsize)
83: take = bp->b_bufsize;
84: pagemove(&bp->b_un.b_addr[bp->b_bufsize - take],
85: &tp->b_un.b_addr[tp->b_bufsize], take);
86: tp->b_bufsize += take;
87: bp->b_bufsize = bp->b_bufsize - take;
88: if (bp->b_bcount > bp->b_bufsize)
89: bp->b_bcount = bp->b_bufsize;
90: if (bp->b_bufsize <= 0) {
91: bremhash(bp);
92: binshash(bp, &bfreelist[BQ_EMPTY]);
93: bp->b_dev = (dev_t)NODEV;
94: bp->b_error = 0;
95: bp->b_flags |= B_INVAL;
96: }
97: brelse(bp);
98: }
99: out:
100: tp->b_bcount = size;
101: return (1);
102: }
103:
104: /*
105: * Release space associated with a buffer.
106: */
107: bfree(bp)
108: struct buf *bp;
109: {
110:
111: bp->b_bcount = 0;
112: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.