diff options
Diffstat (limited to 'sys/kern/vfs_bio.old.c')
| -rw-r--r-- | sys/kern/vfs_bio.old.c | 593 | 
1 files changed, 0 insertions, 593 deletions
| diff --git a/sys/kern/vfs_bio.old.c b/sys/kern/vfs_bio.old.c deleted file mode 100644 index a791bafcc439..000000000000 --- a/sys/kern/vfs_bio.old.c +++ /dev/null @@ -1,593 +0,0 @@ -/* - * Copyright (c) 1989, 1990, 1991, 1992 William F. Jolitz, TeleMuse - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - *    notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - *    notice, this list of conditions and the following disclaimer in the - *    documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - *    must display the following acknowledgement: - *	This software is a component of "386BSD" developed by  -	William F. Jolitz, TeleMuse. - * 4. Neither the name of the developer nor the name "386BSD" - *    may be used to endorse or promote products derived from this software - *    without specific prior written permission. - * - * THIS SOFTWARE IS A COMPONENT OF 386BSD DEVELOPED BY WILLIAM F. JOLITZ  - * AND IS INTENDED FOR RESEARCH AND EDUCATIONAL PURPOSES ONLY. THIS  - * SOFTWARE SHOULD NOT BE CONSIDERED TO BE A COMMERCIAL PRODUCT.  - * THE DEVELOPER URGES THAT USERS WHO REQUIRE A COMMERCIAL PRODUCT  - * NOT MAKE USE THIS WORK. - * - * FOR USERS WHO WISH TO UNDERSTAND THE 386BSD SYSTEM DEVELOPED - * BY WILLIAM F. JOLITZ, WE RECOMMEND THE USER STUDY WRITTEN  - * REFERENCES SUCH AS THE  "PORTING UNIX TO THE 386" SERIES  - * (BEGINNING JANUARY 1991 "DR. DOBBS JOURNAL", USA AND BEGINNING  - * JUNE 1991 "UNIX MAGAZIN", GERMANY) BY WILLIAM F. JOLITZ AND  - * LYNNE GREER JOLITZ, AS WELL AS OTHER BOOKS ON UNIX AND THE  - * ON-LINE 386BSD USER MANUAL BEFORE USE. A BOOK DISCUSSING THE INTERNALS  - * OF 386BSD ENTITLED "386BSD FROM THE INSIDE OUT" WILL BE AVAILABLE LATE 1992. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED.  IN NO EVENT SHALL THE DEVELOPER BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * 	$Id: vfs_bio.old.c,v 1.2 1993/10/16 15:25:18 rgrimes Exp $ - */ - -#include "param.h" -#include "proc.h" -#include "vnode.h" -#include "buf.h" -#include "specdev.h" -#include "mount.h" -#include "malloc.h" -#ifdef notyet -#include "vm/vm.h" -#include "vm/vm_kern.h" -#endif /* notyet */ -#include "resourcevar.h" - -/* - * Initialize buffer headers and related structures. - */ -void bufinit() -{ -	struct bufhd *bh; -	struct buf *bp; - -	/* first, make a null hash table */ -	for(bh = bufhash; bh < bufhash + BUFHSZ; bh++) { -		bh->b_flags = 0; -		bh->b_forw = (struct buf *)bh; -		bh->b_back = (struct buf *)bh; -	} - -	/* next, make a null set of free lists */ -	for(bp = bfreelist; bp < bfreelist + BQUEUES; bp++) { -		bp->b_flags = 0; -		bp->av_forw = bp; -		bp->av_back = bp; -		bp->b_forw = bp; -		bp->b_back = bp; -	} - -	/* finally, initialize each buffer header and stick on empty q */ -	for(bp = buf; bp < buf + nbuf ; bp++) { -		bp->b_flags = B_HEAD | B_INVAL;	/* we're just an empty header */ -		bp->b_dev = NODEV; -		bp->b_vp = 0; -		binstailfree(bp, bfreelist + BQ_EMPTY); -		binshash(bp, bfreelist + BQ_EMPTY); -	} -} - -/* - * Find the block in the buffer pool. - * If the buffer is not present, allocate a new buffer and load - * its contents according to the filesystem fill routine. - */ -bread(vp, blkno, size, cred, bpp) -	struct vnode *vp; -	daddr_t blkno; -	int size; -	struct ucred *cred; -	struct buf **bpp; -{ -	struct buf *bp; -	int rv = 0; - -	bp = getblk (vp, blkno, size); - -	/* if not found in cache, do some I/O */ -	if ((bp->b_flags & B_CACHE) == 0 || (bp->b_flags & B_INVAL) != 0) { -		bp->b_flags |= B_READ; -		bp->b_flags &= ~(B_DONE|B_ERROR|B_INVAL); -		bp->b_rcred = cred; -		VOP_STRATEGY(bp); -		rv = biowait (bp); -	} -	*bpp = bp; -	 -	return (rv); -} - -/* - * Operates like bread, but also starts I/O on the specified - * read-ahead block. [See page 55 of Bach's Book] - */ -breada(vp, blkno, size, rablkno, rabsize, cred, bpp) -	struct vnode *vp; -	daddr_t blkno; int size; -	daddr_t rablkno; int rabsize; -	struct ucred *cred; -	struct buf **bpp; -{ -	struct buf *bp, *rabp; -	int rv = 0, needwait = 0; - -	bp = getblk (vp, blkno, size); - -	/* if not found in cache, do some I/O */ -	if ((bp->b_flags & B_CACHE) == 0 || (bp->b_flags & B_INVAL) != 0) { -		bp->b_flags |= B_READ; -		bp->b_flags &= ~(B_DONE|B_ERROR|B_INVAL); -		bp->b_rcred = cred; -		VOP_STRATEGY(bp); -		needwait++; -	} -	 -	rabp = getblk (vp, rablkno, rabsize); - -	/* if not found in cache, do some I/O (overlapped with first) */ -	if ((rabp->b_flags & B_CACHE) == 0 || (rabp->b_flags & B_INVAL) != 0) { -		rabp->b_flags |= B_READ | B_ASYNC; -		rabp->b_flags &= ~(B_DONE|B_ERROR|B_INVAL); -		rabp->b_rcred = cred; -		VOP_STRATEGY(rabp); -	} else -		brelse(rabp); -	 -	/* wait for original I/O */ -	if (needwait) -		rv = biowait (bp); - -	*bpp = bp; -	return (rv); -} - -/* - * Synchronous write. - * Release buffer on completion. - */ -bwrite(bp) -	register struct buf *bp; -{ -	int rv; - -	if(bp->b_flags & B_INVAL) { -		brelse(bp); -		return (0); -	} else { -		int wasdelayed; - -		if(!(bp->b_flags & B_BUSY))panic("bwrite: not busy"); -		wasdelayed = bp->b_flags & B_DELWRI; -		bp->b_flags &= ~(B_READ|B_DONE|B_ERROR|B_ASYNC|B_DELWRI); -		if(wasdelayed) reassignbuf(bp, bp->b_vp); -		bp->b_flags |= B_DIRTY; -		bp->b_vp->v_numoutput++; -		VOP_STRATEGY(bp); -		rv = biowait(bp); -		brelse(bp); -		return (rv); -	} -} - -/* - * Delayed write. - * - * The buffer is marked dirty, but is not queued for I/O. - * This routine should be used when the buffer is expected - * to be modified again soon, typically a small write that - * partially fills a buffer. - * - * NB: magnetic tapes cannot be delayed; they must be - * written in the order that the writes are requested. - */ -void bdwrite(bp) -	register struct buf *bp; -{ - -	if(!(bp->b_flags & B_BUSY))panic("bdwrite: not busy"); -	if(bp->b_flags & B_INVAL) { -		brelse(bp); -	} -	if(bp->b_flags & B_TAPE) { -		bwrite(bp); -		return; -	} -	bp->b_flags &= ~(B_READ|B_DONE); -	bp->b_flags |= B_DIRTY|B_DELWRI; -	reassignbuf(bp, bp->b_vp); -	brelse(bp); -	return; -} - -/* - * Asynchronous write. - * Start I/O on a buffer, but do not wait for it to complete. - * The buffer is released when the I/O completes. - */ -bawrite(bp) -	register struct buf *bp; -{ - -	if(!(bp->b_flags & B_BUSY))panic("bawrite: not busy"); -	if(bp->b_flags & B_INVAL) -		brelse(bp); -	else { -		int wasdelayed; - -		wasdelayed = bp->b_flags & B_DELWRI; -		bp->b_flags &= ~(B_READ|B_DONE|B_ERROR|B_DELWRI); -		if(wasdelayed) reassignbuf(bp, bp->b_vp); - -		bp->b_flags |= B_DIRTY | B_ASYNC; -		bp->b_vp->v_numoutput++; -		VOP_STRATEGY(bp); -	} -} - -/* - * Release a buffer. - * Even if the buffer is dirty, no I/O is started. - */ -brelse(bp) -	register struct buf *bp; -{ -	int x; - -	/* anyone need a "free" block? */ -	x=splbio(); -	if ((bfreelist + BQ_AGE)->b_flags & B_WANTED) { -		(bfreelist + BQ_AGE) ->b_flags &= ~B_WANTED; -		wakeup(bfreelist); -	} -	/* anyone need this very block? */ -	if (bp->b_flags & B_WANTED) { -		bp->b_flags &= ~B_WANTED; -		wakeup(bp); -	} - -	if (bp->b_flags & (B_INVAL|B_ERROR)) { -		bp->b_flags |= B_INVAL; -		bp->b_flags &= ~(B_DELWRI|B_CACHE); -		if(bp->b_vp) -			brelvp(bp); -	} - -	/* enqueue */ -	/* just an empty buffer head ... */ -	/*if(bp->b_flags & B_HEAD) -		binsheadfree(bp, bfreelist + BQ_EMPTY)*/ -	/* buffers with junk contents */ -	/*else*/ if(bp->b_flags & (B_ERROR|B_INVAL|B_NOCACHE)) -		binsheadfree(bp, bfreelist + BQ_AGE) -	/* buffers with stale but valid contents */ -	else if(bp->b_flags & B_AGE) -		binstailfree(bp, bfreelist + BQ_AGE) -	/* buffers with valid and quite potentially reuseable contents */ -	else -		binstailfree(bp, bfreelist + BQ_LRU) - -	/* unlock */ -	bp->b_flags &= ~B_BUSY; -	splx(x); - -	return; -} - -int freebufspace; -int allocbufspace; - -/* - * Find a buffer which is available for use. - * If free memory for buffer space and an empty header from the empty list, - * use that. Otherwise, select something from a free list. - * Preference is to AGE list, then LRU list. - */ -struct buf * -getnewbuf(sz) -{ -	struct buf *bp; -	int x; - -	x = splbio(); -start: -	/* can we constitute a new buffer? */ -	if (freebufspace > sz -		&& bfreelist[BQ_EMPTY].av_forw != (struct buf *)bfreelist+BQ_EMPTY) { -		caddr_t addr; - -#ifndef notyet -		if ((addr = malloc (sz, M_TEMP, M_NOWAIT)) == 0) goto tryfree; -#else /* notyet */ -		/* get new memory buffer */ -		if (round_page(sz) == sz) -			addr = (caddr_t) kmem_alloc(buffer_map, sz); -		else -			addr = (caddr_t) malloc (sz, M_TEMP, M_WAITOK); -	/*if ((addr = malloc (sz, M_TEMP, M_NOWAIT)) == 0) goto tryfree;*/ -#endif /* notyet */ -		freebufspace -= sz; -		allocbufspace += sz; - -		bp = bfreelist[BQ_EMPTY].av_forw; -		bp->b_flags = B_BUSY | B_INVAL; -		bremfree(bp); -#ifndef notyet -		bp->b_un.b_addr = (caddr_t) addr; -#else /* notyet */ -		bp->b_un.b_addr = addr; -#endif /* notyet */ -		goto fillin; -	} - -tryfree: -	if (bfreelist[BQ_AGE].av_forw != (struct buf *)bfreelist+BQ_AGE) { -		bp = bfreelist[BQ_AGE].av_forw; -		bremfree(bp); -	} else if (bfreelist[BQ_LRU].av_forw != (struct buf *)bfreelist+BQ_LRU) { -		bp = bfreelist[BQ_LRU].av_forw; -		bremfree(bp); -	} else	{ -		/* wait for a free buffer of any kind */ -		(bfreelist + BQ_AGE)->b_flags |= B_WANTED; -		sleep(bfreelist, PRIBIO); -		splx(x); -		return (0); -	} - -	/* if we are a delayed write, convert to an async write! */ -	if (bp->b_flags & B_DELWRI) { -		/*bp->b_flags &= ~B_DELWRI;*/ -		bp->b_flags |= B_BUSY; -		bawrite (bp); -		goto start; -	} - -	/*if (bp->b_flags & (B_INVAL|B_ERROR) == 0) { -		bremhash(bp); -	}*/ - -	if(bp->b_vp) -		brelvp(bp); - -	/* we are not free, nor do we contain interesting data */ -	bp->b_flags = B_BUSY; -fillin: -	bremhash(bp); -	splx(x); -	bp->b_dev = NODEV; -	bp->b_vp = NULL; -	bp->b_blkno = bp->b_lblkno = 0; -	bp->b_iodone = 0; -	bp->b_error = 0; -	bp->b_wcred = bp->b_rcred = NOCRED; -	if (bp->b_bufsize != sz) allocbuf(bp, sz); -	bp->b_bcount = bp->b_bufsize = sz; -	bp->b_dirtyoff = bp->b_dirtyend = 0; -	return (bp); -} - -/* - * Check to see if a block is currently memory resident. - */ -struct buf *incore(vp, blkno) -	struct vnode *vp; -	daddr_t blkno; -{ -	struct buf *bh; -	struct buf *bp; - -	bh = BUFHASH(vp, blkno); - -	/* Search hash chain */ -	bp = bh->b_forw; -	while (bp != (struct buf *) bh) { -		/* hit */ -		if (bp->b_lblkno == blkno && bp->b_vp == vp -			&& (bp->b_flags & B_INVAL) == 0) -			return (bp); -		bp = bp->b_forw; -	} -	 -	return(0); -} - -/* - * Get a block of requested size that is associated with - * a given vnode and block offset. If it is found in the - * block cache, mark it as having been found, make it busy - * and return it. Otherwise, return an empty block of the - * correct size. It is up to the caller to insure that the - * cached blocks be of the correct size. - */ -struct buf * -getblk(vp, blkno, size) -	register struct vnode *vp; -	daddr_t blkno; -	int size; -{ -	struct buf *bp, *bh; -	int x; - -	for (;;) { -		if (bp = incore(vp, blkno)) { -			x = splbio(); -			if (bp->b_flags & B_BUSY) { -				bp->b_flags |= B_WANTED; -				sleep (bp, PRIBIO); -				splx(x); -				continue; -			} -			bp->b_flags |= B_BUSY | B_CACHE; -			bremfree(bp); -			if (size > bp->b_bufsize) -				panic("now what do we do?"); -			/* if (bp->b_bufsize != size) allocbuf(bp, size); */ -		} else { - -			if((bp = getnewbuf(size)) == 0) continue; -			bp->b_blkno = bp->b_lblkno = blkno; -			bgetvp(vp, bp); -			x = splbio(); -			bh = BUFHASH(vp, blkno); -			binshash(bp, bh); -			bp->b_flags = B_BUSY; -		} -		splx(x); -		return (bp); -	} -} - -/* - * Get an empty, disassociated buffer of given size. - */ -struct buf * -geteblk(size) -	int size; -{ -	struct buf *bp; -	int x; - -	while ((bp = getnewbuf(size)) == 0) -		; -	x = splbio(); -	binshash(bp, bfreelist + BQ_AGE); -	splx(x); - -	return (bp); -} - -/* - * Exchange a buffer's underlying buffer storage for one of different - * size, taking care to maintain contents appropriately. When buffer - * increases in size, caller is responsible for filling out additional - * contents. When buffer shrinks in size, data is lost, so caller must - * first return it to backing store before shrinking the buffer, as - * no implied I/O will be done. - * - * Expanded buffer is returned as value. - */ -void -allocbuf(bp, size) -	register struct buf *bp; -	int size; -{ -	caddr_t newcontents; - -	/* get new memory buffer */ -#ifndef notyet -	newcontents = (caddr_t) malloc (size, M_TEMP, M_WAITOK); -#else /* notyet */ -	if (round_page(size) == size) -		newcontents = (caddr_t) kmem_alloc(buffer_map, size); -	else -		newcontents = (caddr_t) malloc (size, M_TEMP, M_WAITOK); -#endif /* notyet */ - -	/* copy the old into the new, up to the maximum that will fit */ -	bcopy (bp->b_un.b_addr, newcontents, min(bp->b_bufsize, size)); - -	/* return old contents to free heap */ -#ifndef notyet -	free (bp->b_un.b_addr, M_TEMP); -#else /* notyet */ -	if (round_page(bp->b_bufsize) == bp->b_bufsize) -		kmem_free(buffer_map, bp->b_un.b_addr, bp->b_bufsize); -	else -		free (bp->b_un.b_addr, M_TEMP); -#endif /* notyet */ - -	/* adjust buffer cache's idea of memory allocated to buffer contents */ -	freebufspace -= size - bp->b_bufsize; -	allocbufspace += size - bp->b_bufsize; - -	/* update buffer header */ -	bp->b_un.b_addr = newcontents; -	bp->b_bcount = bp->b_bufsize = size; -} - -/* - * Patiently await operations to complete on this buffer. - * When they do, extract error value and return it. - * Extract and return any errors associated with the I/O. - * If an invalid block, force it off the lookup hash chains. - */ -biowait(bp) -	register struct buf *bp; -{ -	int x; - -	x = splbio(); -	while ((bp->b_flags & B_DONE) == 0) -		sleep((caddr_t)bp, PRIBIO); -	if((bp->b_flags & B_ERROR) || bp->b_error) { -		if ((bp->b_flags & B_INVAL) == 0) { -			bp->b_flags |= B_INVAL; -			bremhash(bp); -			binshash(bp, bfreelist + BQ_AGE); -		} -		if (!bp->b_error) -			bp->b_error = EIO; -		else -			bp->b_flags |= B_ERROR; -		splx(x); -		return (bp->b_error); -	} else { -		splx(x); -		return (0); -	} -} - -/* - * Finish up operations on a buffer, calling an optional - * function (if requested), and releasing the buffer if - * marked asynchronous. Then mark this buffer done so that - * others biowait()'ing for it will notice when they are - * woken up from sleep(). - */ -biodone(bp) -	register struct buf *bp; -{ -	int x; - -	x = splbio(); -	if (bp->b_flags & B_CALL) (*bp->b_iodone)(bp); -	bp->b_flags &=  ~B_CALL; -	if ((bp->b_flags & (B_READ|B_DIRTY)) == B_DIRTY)  { -		bp->b_flags &=  ~B_DIRTY; -		vwakeup(bp); -	} -	if (bp->b_flags & B_ASYNC) -		brelse(bp); -	bp->b_flags &=  ~B_ASYNC; -	bp->b_flags |= B_DONE; -	wakeup(bp); -	splx(x); -} | 
