- for (i = 0; i < num; i++) {
- if (incore(vp, rablkno[i]))
- continue;
- rabp = getblk(vp, rablkno[i], rabsize[i]);
-#endif SECSIZE
- if (rabp->b_flags & (B_DONE | B_DELWRI)) {
- brelse(rabp);
- trace(TR_BREADHITRA, pack(vp, rabsize[i]), rablkno[i]);
- } else {
- rabp->b_flags |= B_ASYNC | B_READ;
- if (rabp->b_bcount > rabp->b_bufsize)
- panic("breadrabp");
- if (rabp->b_rcred == NOCRED && cred != NOCRED) {
- crhold(cred);
- rabp->b_rcred = cred;
+ rbp = NULL;
+ if (lblkno != vp->v_lastr + 1 && lblkno != 0)
+ vp->v_ralen = max(vp->v_ralen >> 1, 1);
+ else if ((ioblkno + 1) * size < filesize && !alreadyincore &&
+ !(error = VOP_BMAP(vp, ioblkno, NULL, &blkno, &num_ra))) {
+ /*
+ * Reading sequentially, and the next block is not in the
+ * cache. We are going to try reading ahead. If this is
+ * the first read of a file, then limit read-ahead to a
+ * single block, else read as much as we're allowed.
+ */
+ if (num_ra > vp->v_ralen) {
+ num_ra = vp->v_ralen;
+ vp->v_ralen = min(MAXPHYS / size, vp->v_ralen << 1);
+ } else
+ vp->v_ralen = num_ra + 1;
+
+
+ if (num_ra) /* case 2, 4 */
+ rbp = cluster_rbuild(vp, filesize,
+ bp, ioblkno, blkno, size, num_ra, flags);
+ else if (lblkno != 0 && ioblkno == lblkno) {
+ /* Case 5: check how many blocks to read ahead */
+ ++ioblkno;
+ if ((ioblkno + 1) * size > filesize ||
+ (error = VOP_BMAP(vp,
+ ioblkno, NULL, &blkno, &num_ra)))
+ goto skip_readahead;
+ flags |= B_ASYNC;
+ if (num_ra)
+ rbp = cluster_rbuild(vp, filesize,
+ NULL, ioblkno, blkno, size, num_ra, flags);
+ else {
+ rbp = getblk(vp, ioblkno, size, 0, 0);
+ rbp->b_flags |= flags;
+ rbp->b_blkno = blkno;