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