+/*
+ * Malloc buffers and set up cache.
+ */
+bufinit()
+{
+ register BUFAREA *bp;
+ long bufcnt, i;
+ char *bufp;
+
+ bufp = (char *)malloc(sblock.fs_bsize);
+ if (bufp == 0)
+ errexit("cannot allocate buffer pool\n");
+ cgblk.b_un.b_buf = bufp;
+ initbarea(&cgblk);
+ bufhead.b_next = bufhead.b_prev = &bufhead;
+ bufcnt = MAXBUFSPACE / sblock.fs_bsize;
+ if (bufcnt < MINBUFS)
+ bufcnt = MINBUFS;
+ for (i = 0; i < bufcnt; i++) {
+ bp = (BUFAREA *)malloc(sizeof(BUFAREA));
+ bufp = (char *)malloc(sblock.fs_bsize);
+ if (bp == 0 || bufp == 0) {
+ if (i >= MINBUFS)
+ break;
+ errexit("cannot allocate buffer pool\n");
+ }
+ bp->b_un.b_buf = bufp;
+ bp->b_prev = &bufhead;
+ bp->b_next = bufhead.b_next;
+ bufhead.b_next->b_prev = bp;
+ bufhead.b_next = bp;
+ initbarea(bp);
+ }
+}
+
+/*
+ * Manage a cache of directory blocks.
+ */
+BUFAREA *
+getdatablk(blkno, size)
+ daddr_t blkno;
+ long size;
+{
+ register BUFAREA *bp;
+
+ for (bp = bufhead.b_next; bp != &bufhead; bp = bp->b_next)
+ if (bp->b_bno == blkno)
+ goto foundit;
+ for (bp = bufhead.b_prev; bp != &bufhead; bp = bp->b_prev)
+ if ((bp->b_flags & B_INUSE) == 0)
+ break;
+ if (bp == &bufhead)
+ errexit("deadlocked buffer pool\n");
+ getblk(bp, blkno, size);
+ /* fall through */
+foundit:
+ totalreads++;
+ bp->b_prev->b_next = bp->b_next;
+ bp->b_next->b_prev = bp->b_prev;
+ bp->b_prev = &bufhead;
+ bp->b_next = bufhead.b_next;
+ bufhead.b_next->b_prev = bp;
+ bufhead.b_next = bp;
+ bp->b_flags |= B_INUSE;
+ return (bp);
+}
+