- panic("bread: size 0");
-#ifdef SECSIZE
- bp = getblk(dev, blkno, size, secsize);
-#else SECSIZE
- *bpp = bp = getblk(vp, blkno, size);
-#endif SECSIZE
- if (bp->b_flags & (B_DONE | B_DELWRI)) {
- trace(TR_BREADHIT, pack(vp, size), blkno);
- return (0);
- }
- bp->b_flags |= B_READ;
- if (bp->b_bcount > bp->b_bufsize)
- panic("bread");
- if (bp->b_rcred == NOCRED && cred != NOCRED) {
- crhold(cred);
- bp->b_rcred = cred;
- }
- VOP_STRATEGY(bp);
- trace(TR_BREADMISS, pack(vp, size), blkno);
- p->p_stats->p_ru.ru_inblock++; /* pay for read */
- return (biowait(bp));
-}
-
-/*
- * Operates like bread, but also starts I/O on the specified
- * read-ahead block.
- */
-breada(vp, blkno, size, rablkno, rabsize, cred, bpp)
- struct vnode *vp;
- daddr_t blkno; int size;
-#ifdef SECSIZE
- long secsize;
-#endif SECSIZE
- daddr_t rablkno; int rabsize;
- struct ucred *cred;
- struct buf **bpp;
-{
- struct proc *p = curproc; /* XXX */
- register struct buf *bp, *rabp;
-
- bp = NULL;
- /*
- * If the block is not memory resident,
- * allocate a buffer and start I/O.
- */
- if (!incore(vp, blkno)) {
- *bpp = bp = getblk(vp, blkno, size);
-#endif SECSIZE
- if ((bp->b_flags & (B_DONE | B_DELWRI)) == 0) {
- bp->b_flags |= B_READ;
- if (bp->b_bcount > bp->b_bufsize)
- panic("breada");
- if (bp->b_rcred == NOCRED && cred != NOCRED) {
- crhold(cred);
- bp->b_rcred = cred;
- }
- VOP_STRATEGY(bp);
- trace(TR_BREADMISS, pack(vp, size), blkno);
- p->p_stats->p_ru.ru_inblock++; /* pay for read */
- } else
- trace(TR_BREADHIT, pack(vp, size), blkno);
+ panic("cluster_read: size = 0");
+#endif
+
+ error = 0;
+ flags = B_READ;
+ *bpp = bp = getblk(vp, lblkno, size, 0, 0);
+ if (bp->b_flags & (B_CACHE | B_DONE | B_DELWRI)) {
+ /*
+ * Desired block is in cache; do any readahead ASYNC.
+ * Case 1, 2.
+ */
+ trace(TR_BREADHIT, pack(vp, size), lblkno);
+ flags |= B_ASYNC;
+ ioblkno = lblkno +
+ (lblkno < vp->v_ralen ? vp->v_ralen >> 1 : vp->v_ralen);
+ alreadyincore = (int)incore(vp, ioblkno);
+ bp = NULL;
+ } else {
+ /* Block wasn't in cache, case 3, 4, 5. */
+ trace(TR_BREADMISS, pack(vp, size), lblkno);
+ ioblkno = lblkno;
+ bp->b_flags |= flags;
+ alreadyincore = 0;
+ curproc->p_stats->p_ru.ru_inblock++; /* XXX */