|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)ufs_machdep.c 7.4 (Berkeley) 2/17/90 ! 7: */ ! 8: ! 9: #include "pte.h" ! 10: ! 11: #include "param.h" ! 12: #include "systm.h" ! 13: #include "user.h" ! 14: #include "buf.h" ! 15: #include "conf.h" ! 16: #include "proc.h" ! 17: #include "seg.h" ! 18: #include "vm.h" ! 19: ! 20: /* ! 21: * Machine dependent handling of the buffer cache. ! 22: */ ! 23: ! 24: /* ! 25: * Expand or contract the actual memory allocated to a buffer. ! 26: * If no memory is available, release buffer and take error exit ! 27: */ ! 28: allocbuf(tp, size) ! 29: register struct buf *tp; ! 30: int size; ! 31: { ! 32: register struct buf *bp, *ep; ! 33: int sizealloc, take, s; ! 34: ! 35: sizealloc = roundup(size, CLBYTES); ! 36: /* ! 37: * Buffer size does not change ! 38: */ ! 39: if (sizealloc == tp->b_bufsize) ! 40: goto out; ! 41: /* ! 42: * Buffer size is shrinking. ! 43: * Place excess space in a buffer header taken from the ! 44: * BQ_EMPTY buffer list and placed on the "most free" list. ! 45: * If no extra buffer headers are available, leave the ! 46: * extra space in the present buffer. ! 47: */ ! 48: if (sizealloc < tp->b_bufsize) { ! 49: ep = bfreelist[BQ_EMPTY].av_forw; ! 50: if (ep == &bfreelist[BQ_EMPTY]) ! 51: goto out; ! 52: s = splbio(); ! 53: bremfree(ep); ! 54: ep->b_flags |= B_BUSY; ! 55: splx(s); ! 56: pagemove(tp->b_un.b_addr + sizealloc, ep->b_un.b_addr, ! 57: (int)tp->b_bufsize - sizealloc); ! 58: ep->b_bufsize = tp->b_bufsize - sizealloc; ! 59: tp->b_bufsize = sizealloc; ! 60: ep->b_flags |= B_INVAL; ! 61: ep->b_bcount = 0; ! 62: brelse(ep); ! 63: goto out; ! 64: } ! 65: /* ! 66: * More buffer space is needed. Get it out of buffers on ! 67: * the "most free" list, placing the empty headers on the ! 68: * BQ_EMPTY buffer header list. ! 69: */ ! 70: while (tp->b_bufsize < sizealloc) { ! 71: take = sizealloc - tp->b_bufsize; ! 72: bp = getnewbuf(); ! 73: if (take >= bp->b_bufsize) ! 74: take = bp->b_bufsize; ! 75: pagemove(&bp->b_un.b_addr[bp->b_bufsize - take], ! 76: &tp->b_un.b_addr[tp->b_bufsize], take); ! 77: tp->b_bufsize += take; ! 78: bp->b_bufsize = bp->b_bufsize - take; ! 79: if (bp->b_bcount > bp->b_bufsize) ! 80: bp->b_bcount = bp->b_bufsize; ! 81: if (bp->b_bufsize <= 0) { ! 82: bremhash(bp); ! 83: binshash(bp, &bfreelist[BQ_EMPTY]); ! 84: bp->b_dev = (dev_t)NODEV; ! 85: bp->b_error = 0; ! 86: bp->b_flags |= B_INVAL; ! 87: } ! 88: brelse(bp); ! 89: } ! 90: out: ! 91: tp->b_bcount = size; ! 92: return (1); ! 93: } ! 94: ! 95: /* ! 96: * Release space associated with a buffer. ! 97: */ ! 98: bfree(bp) ! 99: struct buf *bp; ! 100: { ! 101: ! 102: bp->b_bcount = 0; ! 103: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.