* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: vfs__bio.c,v 1.12 1993/11/26 19:08:26 wollman Exp $
+ * $Id: vfs__bio.c,v 1.20 1994/05/29 07:34:15 davidg Exp $
*/
#include "param.h"
struct buf *bclnlist; /* head of cleaned page list */
static struct buf *getnewbuf(int);
-extern vm_map_t buffer_map;
+extern vm_map_t buffer_map, io_map;
+
+/*
+ * Internel update daemon, process 3
+ * The variable vfs_update_wakeup allows for internal syncs.
+ */
+int vfs_update_wakeup;
/*
* Initialize buffer headers and related structures.
&& bfreelist[BQ_EMPTY].av_forw != (struct buf *)bfreelist+BQ_EMPTY) {
caddr_t addr;
-/*#define notyet*/
-#ifndef notyet
- if ((addr = malloc (sz, M_TEMP, M_WAITOK)) == 0) goto tryfree;
-#else /* notyet */
- /* get new memory buffer */
- if (round_page(sz) == sz)
- addr = (caddr_t) kmem_alloc_wired_wait(buffer_map, sz);
- else
- addr = (caddr_t) malloc (sz, M_TEMP, M_WAITOK);
- /*if ((addr = malloc (sz, M_TEMP, M_NOWAIT)) == 0) goto tryfree;*/
- bzero(addr, sz);
-#endif /* notyet */
+ if ((addr = malloc (sz, M_IOBUF, M_NOWAIT)) == 0)
+ goto tryfree;
freebufspace -= sz;
allocbufspace += sz;
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;
- tsleep ((caddr_t)bp, PRIBIO, "getblk", 0);
- 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;
+ x = splbio();
+loop:
+ if (bp = incore(vp, blkno)) {
+ if (bp->b_flags & B_BUSY) {
+ bp->b_flags |= B_WANTED;
+ tsleep ((caddr_t)bp, PRIBIO, "getblk", 0);
+ goto loop;
}
- splx(x);
- return (bp);
+ 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)
+ goto loop;
+ if ( incore(vp, blkno)) {
+ bp->b_flags |= B_INVAL;
+ brelse(bp);
+ goto loop;
+ }
+
+ bp->b_blkno = bp->b_lblkno = blkno;
+ bgetvp(vp, bp);
+ bh = BUFHASH(vp, blkno);
+ binshash(bp, bh);
+ bp->b_flags = B_BUSY;
}
+ splx(x);
+ return (bp);
}
/*
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_wired_wait(buffer_map, size);
- else
- newcontents = (caddr_t) malloc (size, M_TEMP, M_WAITOK);
-#endif /* notyet */
+ newcontents = (caddr_t) malloc (size, M_IOBUF, M_WAITOK);
/* 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_wakeup(buffer_map, bp->b_un.b_addr, bp->b_bufsize);
- else
- free (bp->b_un.b_addr, M_TEMP);
-#endif /* notyet */
+ free (bp->b_un.b_addr, M_IOBUF);
/* adjust buffer cache's idea of memory allocated to buffer contents */
freebufspace -= size - bp->b_bufsize;
void
biodone(register struct buf *bp)
{
+ int s;
+ s = splbio();
+ if (bp->b_flags & B_CLUSTER) {
+ struct buf *tbp;
+ bp->b_resid = bp->b_bcount;
+ while ( tbp = bp->b_clusterf) {
+ bp->b_clusterf = tbp->av_forw;
+ bp->b_resid -= tbp->b_bcount;
+ tbp->b_resid = 0;
+ if( bp->b_resid <= 0) {
+ tbp->b_error = bp->b_error;
+ tbp->b_flags |= (bp->b_flags & B_ERROR);
+ tbp->b_resid = -bp->b_resid;
+ bp->b_resid = 0;
+ }
+/*
+ printf("rdc (%d,%d,%d) ", tbp->b_blkno, tbp->b_bcount, tbp->b_resid);
+*/
+
+ biodone(tbp);
+ }
+#ifndef NOBOUNCE
+ vm_bounce_kva_free( bp->b_un.b_addr, bp->b_bufsize, 0);
+#endif
+ relpbuf(bp);
+ splx(s);
+ return;
+ }
+
+#ifndef NOBOUNCE
+ if (bp->b_flags & B_BOUNCE)
+ vm_bounce_free(bp);
+#endif
bp->b_flags |= B_DONE;
if ((bp->b_flags & B_READ) == 0) {
if (bp->b_flags & B_CALL) {
bp->b_flags &= ~B_CALL;
(*bp->b_iodone)(bp);
+ splx(s);
return;
}
bp->b_flags &= ~B_WANTED;
wakeup((caddr_t) bp);
}
+ splx(s);
}
-/*
- * Internel update daemon, process 3
- * The variable vfs_update_wakeup allows for internal syncs.
- */
-int vfs_update_wakeup;
+#ifndef UPDATE_INTERVAL
+int vfs_update_interval = 30;
+#else
+int vfs_update_interval = UPDATE_INTERVAL;
+#endif
void
vfs_update() {
(void) spl0();
while(1) {
- tsleep((caddr_t)&vfs_update_wakeup, PRIBIO, "update", hz*30);
+ tsleep((caddr_t)&vfs_update_wakeup, PRIBIO, "update",
+ hz * vfs_update_interval);
vfs_update_wakeup = 0;
sync(curproc, NULL, NULL);
}