|
|
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.5 (Berkeley) 6/28/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.