diff options
-rw-r--r-- | sys/fs/cd9660/cd9660_vnops.c | 5 | ||||
-rw-r--r-- | sys/isofs/cd9660/cd9660_vnops.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_descrip.c | 3 | ||||
-rw-r--r-- | sys/kern/vfs_cluster.c | 308 | ||||
-rw-r--r-- | sys/kern/vfs_export.c | 4 | ||||
-rw-r--r-- | sys/kern/vfs_subr.c | 4 | ||||
-rw-r--r-- | sys/kern/vfs_vnops.c | 38 | ||||
-rw-r--r-- | sys/sys/bio.h | 7 | ||||
-rw-r--r-- | sys/sys/buf.h | 7 | ||||
-rw-r--r-- | sys/sys/file.h | 9 | ||||
-rw-r--r-- | sys/sys/filedesc.h | 4 | ||||
-rw-r--r-- | sys/sys/vnode.h | 4 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_readwrite.c | 18 |
13 files changed, 256 insertions, 160 deletions
diff --git a/sys/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c index 8ac9cd4..e48ddce 100644 --- a/sys/fs/cd9660/cd9660_vnops.c +++ b/sys/fs/cd9660/cd9660_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)cd9660_vnops.c 8.3 (Berkeley) 1/23/94 - * $Id: cd9660_vnops.c,v 1.26 1996/09/20 05:51:12 nate Exp $ + * $Id: cd9660_vnops.c,v 1.27 1996/10/20 21:01:43 alex Exp $ */ #include <sys/param.h> @@ -342,7 +342,8 @@ cd9660_read(ap) if (doclusterread) { if (iso_lblktosize(imp, rablock) <= ip->i_size) error = cluster_read(vp, ip->i_size, - lbn, size, NOCRED, &bp); + lbn, size, NOCRED, uio->uio_resid, + (ap->a_ioflag >> 16), &bp); else error = bread(vp, lbn, size, NOCRED, &bp); } else { diff --git a/sys/isofs/cd9660/cd9660_vnops.c b/sys/isofs/cd9660/cd9660_vnops.c index 8ac9cd4..e48ddce 100644 --- a/sys/isofs/cd9660/cd9660_vnops.c +++ b/sys/isofs/cd9660/cd9660_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)cd9660_vnops.c 8.3 (Berkeley) 1/23/94 - * $Id: cd9660_vnops.c,v 1.26 1996/09/20 05:51:12 nate Exp $ + * $Id: cd9660_vnops.c,v 1.27 1996/10/20 21:01:43 alex Exp $ */ #include <sys/param.h> @@ -342,7 +342,8 @@ cd9660_read(ap) if (doclusterread) { if (iso_lblktosize(imp, rablock) <= ip->i_size) error = cluster_read(vp, ip->i_size, - lbn, size, NOCRED, &bp); + lbn, size, NOCRED, uio->uio_resid, + (ap->a_ioflag >> 16), &bp); else error = bread(vp, lbn, size, NOCRED, &bp); } else { diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index dbbd616..8c6ec05 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)kern_descrip.c 8.6 (Berkeley) 4/19/94 - * $Id: kern_descrip.c,v 1.33 1996/12/19 19:41:35 bde Exp $ + * $Id: kern_descrip.c,v 1.34 1996/12/19 19:59:51 bde Exp $ */ #include <sys/param.h> @@ -674,6 +674,7 @@ falloc(p, resultfp, resultfd) p->p_fd->fd_ofiles[i] = fp; fp->f_count = 1; fp->f_cred = p->p_ucred; + fp->f_seqcount = 1; crhold(fp->f_cred); if (resultfp) *resultfp = fp; diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c index d45663a..064977b 100644 --- a/sys/kern/vfs_cluster.c +++ b/sys/kern/vfs_cluster.c @@ -33,7 +33,7 @@ * SUCH DAMAGE. * * @(#)vfs_cluster.c 8.7 (Berkeley) 2/13/94 - * $Id: vfs_cluster.c,v 1.38 1996/10/06 07:50:04 dyson Exp $ + * $Id: vfs_cluster.c,v 1.39 1996/11/30 22:41:41 dyson Exp $ */ #include <sys/param.h> @@ -52,6 +52,13 @@ #include <vm/vm_object.h> #include <vm/vm_page.h> +#if defined(CLUSTERDEBUG) +#include <sys/sysctl.h> +#include <sys/kernel.h> +static int rcluster= 0; +SYSCTL_INT(_debug, 14, rcluster, CTLFLAG_RW, &rcluster, 0, ""); +#endif + #ifdef notyet_block_reallocation_enabled #ifdef DEBUG #include <sys/sysctl.h> @@ -70,171 +77,197 @@ static struct cluster_save * #endif static struct buf * cluster_rbuild __P((struct vnode *vp, u_quad_t filesize, daddr_t lbn, - daddr_t blkno, long size, int run)); + daddr_t blkno, long size, int run, struct buf *fbp)); -static int totreads; -static int totreadblocks; extern vm_page_t bogus_page; -#ifdef DIAGNOSTIC /* - * Set to 1 if reads of block zero should cause readahead to be done. - * Set to 0 treats a read of block zero as a non-sequential read. - * - * Setting to one assumes that most reads of block zero of files are due to - * sequential passes over the files (e.g. cat, sum) where additional blocks - * will soon be needed. Setting to zero assumes that the majority are - * surgical strikes to get particular info (e.g. size, file) where readahead - * blocks will not be used and, in fact, push out other potentially useful - * blocks from the cache. The former seems intuitive, but some quick tests - * showed that the latter performed better from a system-wide point of view. + * Maximum number of blocks for read-ahead. */ - int doclusterraz = 0; - -#define ISSEQREAD(vp, blk) \ - (((blk) != 0 || doclusterraz) && \ - ((blk) == (vp)->v_lastr + 1 || (blk) == (vp)->v_lastr)) -#else -#define ISSEQREAD(vp, blk) \ - (/* (blk) != 0 && */ ((blk) == (vp)->v_lastr + 1 || (blk) == (vp)->v_lastr)) -#endif +#define MAXRA 32 /* - * allow for three entire read-aheads... The system will - * adjust downwards rapidly if needed... - */ -#define RA_MULTIPLE_FAST 2 -#define RA_MULTIPLE_SLOW 3 -#define RA_SHIFTDOWN 1 /* approx lg2(RA_MULTIPLE) */ -/* - * This replaces bread. If this is a bread at the beginning of a file and - * lastr is 0, we assume this is the first read and we'll read up to two - * blocks if they are sequential. After that, we'll do regular read ahead - * in clustered chunks. - * bp is the block requested. - * rbp is the read-ahead block. - * If either is NULL, then you don't have to do the I/O. + * This replaces bread. */ int -cluster_read(vp, filesize, lblkno, size, cred, bpp) +cluster_read(vp, filesize, lblkno, size, cred, totread, seqcount, bpp) struct vnode *vp; u_quad_t filesize; daddr_t lblkno; long size; struct ucred *cred; + long totread; + int seqcount; struct buf **bpp; { - struct buf *bp, *rbp; - daddr_t blkno, rablkno, origlblkno; - int error, num_ra, alreadyincore; + struct buf *bp, *rbp, *reqbp; + daddr_t blkno, rablkno, origblkno; + int error, num_ra; int i; - int seq; + int maxra, racluster; + long origtotread; error = 0; + + /* + * Try to limit the amount of read-ahead by a few + * ad-hoc parameters. This needs work!!! + */ + racluster = MAXPHYS/size; + maxra = 2 * racluster + (totread / size); + if (maxra > MAXRA) + maxra = MAXRA; + if (maxra > nbuf/8) + maxra = nbuf/8; + /* * get the requested block */ - origlblkno = lblkno; - *bpp = bp = getblk(vp, lblkno, size, 0, 0); + *bpp = reqbp = bp = getblk(vp, lblkno, size, 0, 0); + origblkno = lblkno; + origtotread = totread; - seq = ISSEQREAD(vp, lblkno); /* * if it is in the cache, then check to see if the reads have been * sequential. If they have, then try some read-ahead, otherwise * back-off on prospective read-aheads. */ if (bp->b_flags & B_CACHE) { - if (!seq) { - vp->v_maxra = bp->b_lblkno + bp->b_bcount / size; - vp->v_ralen >>= RA_SHIFTDOWN; + if (!seqcount) { + return 0; + } else if ((bp->b_flags & B_RAM) == 0) { return 0; - } else if( vp->v_maxra > lblkno) { - if ((vp->v_ralen + 1) < RA_MULTIPLE_FAST * (MAXPHYS / size)) - ++vp->v_ralen; - if ( vp->v_maxra > lblkno + vp->v_ralen ) { + } else { + int s; + struct buf *tbp; + bp->b_flags &= ~B_RAM; + /* + * We do the spl here so that there is no window + * between the incore and the b_usecount increment + * below. We opt to keep the spl out of the loop + * for efficiency. + */ + s = splbio(); + for(i=1;i<maxra;i++) { + + if (!(tbp = incore(vp, lblkno+i))) { + break; + } + + /* + * Set another read-ahead mark so we know to check + * again. + */ + if (((i % racluster) == (racluster - 1)) || + (i == (maxra - 1))) + tbp->b_flags |= B_RAM; + +#if 0 + if (tbp->b_usecount == 0) { + /* + * Make sure that the soon-to-be used readaheads + * are still there. The getblk/bqrelse pair will + * boost the priority of the buffer. + */ + tbp = getblk(vp, lblkno+i, size, 0, 0); + bqrelse(tbp); + } +#endif + } + splx(s); + if (i >= maxra) { return 0; } - lblkno = vp->v_maxra; + lblkno += i; + } + reqbp = bp = NULL; + } else { + u_quad_t firstread; + firstread = (u_quad_t) lblkno * size; + if (firstread + totread > filesize) + totread = filesize - firstread; + if (totread > size) { + int nblks = 0; + int ncontigafter; + while (totread > 0) { + nblks++; + totread -= size; + } + if (nblks == 1) + goto single_block_read; + if (nblks > racluster) + nblks = racluster; + + error = VOP_BMAP(vp, lblkno, NULL, + &blkno, &ncontigafter, NULL); + if (error) + goto single_block_read; + if (blkno == -1) + goto single_block_read; + if (ncontigafter == 0) + goto single_block_read; + if (ncontigafter + 1 < nblks) + nblks = ncontigafter + 1; + + bp = cluster_rbuild(vp, filesize, lblkno, + blkno, size, nblks, bp); + lblkno += nblks; } else { +single_block_read: + /* + * if it isn't in the cache, then get a chunk from + * disk if sequential, otherwise just get the block. + */ + bp->b_flags |= B_READ | B_RAM; lblkno += 1; } - bp = NULL; - } else { - /* - * if it isn't in the cache, then get a chunk from disk if - * sequential, otherwise just get the block. - */ - bp->b_flags |= B_READ; - lblkno += 1; - curproc->p_stats->p_ru.ru_inblock++; /* XXX */ - vp->v_ralen = 0; } - /* - * assume no read-ahead - */ - alreadyincore = 1; - rablkno = lblkno; /* * if we have been doing sequential I/O, then do some read-ahead */ - if (seq) { - alreadyincore = 0; - - /* - * bump ralen a bit... - */ - if ((vp->v_ralen + 1) < RA_MULTIPLE_SLOW*(MAXPHYS / size)) - ++vp->v_ralen; + rbp = NULL; + /* if (seqcount && (lblkno < (origblkno + maxra))) { */ + if (seqcount && (lblkno < (origblkno + seqcount))) { /* - * this code makes sure that the stuff that we have read-ahead - * is still in the cache. If it isn't, we have been reading - * ahead too much, and we need to back-off, otherwise we might - * try to read more. + * we now build the read-ahead buffer if it is desirable. */ - for (i = 0; i < vp->v_maxra - lblkno; i++) { - rablkno = lblkno + i; - alreadyincore = (int) incore(vp, rablkno); - if (!alreadyincore) { - vp->v_maxra = rablkno; - vp->v_ralen >>= RA_SHIFTDOWN; - alreadyincore = 1; + if (((u_quad_t)(lblkno + 1) * size) <= filesize && + !(error = VOP_BMAP(vp, lblkno, NULL, &blkno, &num_ra, NULL)) && + blkno != -1) { + int nblksread; + int ntoread = num_ra + 1; + nblksread = (origtotread + size - 1) / size; + if (seqcount < nblksread) + seqcount = nblksread; + if (seqcount < ntoread) + ntoread = seqcount; + if (num_ra) { + rbp = cluster_rbuild(vp, filesize, lblkno, + blkno, size, ntoread, NULL); + } else { + rbp = getblk(vp, lblkno, size, 0, 0); + rbp->b_flags |= B_READ | B_ASYNC | B_RAM; + rbp->b_blkno = blkno; } } } - /* - * we now build the read-ahead buffer if it is desirable. - */ - rbp = NULL; - if (!alreadyincore && - ((u_quad_t)(rablkno + 1) * size) <= filesize && - !(error = VOP_BMAP(vp, rablkno, NULL, &blkno, &num_ra, NULL)) && - blkno != -1) { - if (num_ra > vp->v_ralen) - num_ra = vp->v_ralen; - - if (num_ra) { - rbp = cluster_rbuild(vp, filesize, rablkno, blkno, size, - num_ra + 1); - } else { - rbp = getblk(vp, rablkno, size, 0, 0); - rbp->b_flags |= B_READ | B_ASYNC; - rbp->b_blkno = blkno; - } - } /* * handle the synchronous read */ if (bp) { - if (bp->b_flags & (B_DONE | B_DELWRI)) + if (bp->b_flags & (B_DONE | B_DELWRI)) { panic("cluster_read: DONE bp"); - else { - vfs_busy_pages(bp, 0); + } else { +#if defined(CLUSTERDEBUG) + if (rcluster) + printf("S(%d,%d,%d) ", + bp->b_lblkno, bp->b_bcount, seqcount); +#endif + if ((bp->b_flags & B_CLUSTER) == 0) + vfs_busy_pages(bp, 0); error = VOP_STRATEGY(bp); - vp->v_maxra = bp->b_lblkno + bp->b_bcount / size; - totreads++; - totreadblocks += bp->b_bcount / size; curproc->p_stats->p_ru.ru_inblock++; } } @@ -242,7 +275,6 @@ cluster_read(vp, filesize, lblkno, size, cred, bpp) * and if we have read-aheads, do them too */ if (rbp) { - vp->v_maxra = rbp->b_lblkno + rbp->b_bcount / size; if (error) { rbp->b_flags &= ~(B_ASYNC | B_READ); brelse(rbp); @@ -250,17 +282,31 @@ cluster_read(vp, filesize, lblkno, size, cred, bpp) rbp->b_flags &= ~(B_ASYNC | B_READ); bqrelse(rbp); } else { +#if defined(CLUSTERDEBUG) + if (rcluster) { + if (bp) + printf("A+(%d,%d,%d,%d) ", + rbp->b_lblkno, rbp->b_bcount, + rbp->b_lblkno - origblkno, + seqcount); + else + printf("A(%d,%d,%d,%d) ", + rbp->b_lblkno, rbp->b_bcount, + rbp->b_lblkno - origblkno, + seqcount); + } +#endif + if ((rbp->b_flags & B_CLUSTER) == 0) vfs_busy_pages(rbp, 0); (void) VOP_STRATEGY(rbp); - totreads++; - totreadblocks += rbp->b_bcount / size; curproc->p_stats->p_ru.ru_inblock++; } } - if (bp && ((bp->b_flags & B_ASYNC) == 0)) - return (biowait(bp)); - return (error); + if (reqbp) + return (biowait(reqbp)); + else + return (error); } /* @@ -269,13 +315,14 @@ cluster_read(vp, filesize, lblkno, size, cred, bpp) * and then parcel them up into logical blocks in the buffer hash table. */ static struct buf * -cluster_rbuild(vp, filesize, lbn, blkno, size, run) +cluster_rbuild(vp, filesize, lbn, blkno, size, run, fbp) struct vnode *vp; u_quad_t filesize; daddr_t lbn; daddr_t blkno; long size; int run; + struct buf *fbp; { struct buf *bp, *tbp; daddr_t bn; @@ -293,12 +340,17 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run) --run; } - tbp = getblk(vp, lbn, size, 0, 0); - if (tbp->b_flags & B_CACHE) - return tbp; + if (fbp) { + tbp = fbp; + tbp->b_flags |= B_READ; + } else { + tbp = getblk(vp, lbn, size, 0, 0); + if (tbp->b_flags & B_CACHE) + return tbp; + tbp->b_flags |= B_ASYNC | B_READ | B_RAM; + } tbp->b_blkno = blkno; - tbp->b_flags |= B_ASYNC | B_READ; if( (tbp->b_flags & B_MALLOC) || ((tbp->b_flags & B_VMIO) == 0) || (run <= 1) ) return tbp; @@ -353,6 +405,8 @@ cluster_rbuild(vp, filesize, lbn, blkno, size, run) break; } + if ((fbp && (i == 1)) || (i == (run - 1))) + tbp->b_flags |= B_RAM; tbp->b_flags |= B_READ | B_ASYNC; if (tbp->b_blkno == tbp->b_lblkno) { tbp->b_blkno = bn; @@ -419,9 +473,9 @@ cluster_callback(bp) * Move memory from the large cluster buffer into the component * buffers and mark IO as done on these. */ - for (tbp = bp->b_cluster.cluster_head.tqh_first; + for (tbp = TAILQ_FIRST(&bp->b_cluster.cluster_head); tbp; tbp = nbp) { - nbp = tbp->b_cluster.cluster_entry.tqe_next; + nbp = TAILQ_NEXT(&tbp->b_cluster, cluster_entry); if (error) { tbp->b_flags |= B_ERROR; tbp->b_error = error; diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index ae27ae2..b4e1db4 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_subr.c 8.13 (Berkeley) 4/18/94 - * $Id: vfs_subr.c,v 1.64 1996/10/28 11:34:57 phk Exp $ + * $Id: vfs_subr.c,v 1.65 1996/11/12 09:24:31 bde Exp $ */ /* @@ -393,8 +393,6 @@ retry: #endif vp->v_flag = 0; vp->v_lastr = 0; - vp->v_ralen = 0; - vp->v_maxra = 0; vp->v_lastw = 0; vp->v_lasta = 0; vp->v_cstart = 0; diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index ae27ae2..b4e1db4 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_subr.c 8.13 (Berkeley) 4/18/94 - * $Id: vfs_subr.c,v 1.64 1996/10/28 11:34:57 phk Exp $ + * $Id: vfs_subr.c,v 1.65 1996/11/12 09:24:31 bde Exp $ */ /* @@ -393,8 +393,6 @@ retry: #endif vp->v_flag = 0; vp->v_lastr = 0; - vp->v_ralen = 0; - vp->v_maxra = 0; vp->v_lastw = 0; vp->v_lasta = 0; vp->v_cstart = 0; diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index abc85c4..5d9c6ee 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94 - * $Id: vfs_vnops.c,v 1.25 1996/03/09 06:42:15 dyson Exp $ + * $Id: vfs_vnops.c,v 1.26 1996/08/21 21:55:23 dyson Exp $ */ #include <sys/param.h> @@ -273,14 +273,46 @@ vn_read(fp, uio, cred) { register struct vnode *vp = (struct vnode *)fp->f_data; int count, error; + int flag, seq; LEASE_CHECK(vp, uio->uio_procp, cred, LEASE_READ); VOP_LOCK(vp); uio->uio_offset = fp->f_offset; count = uio->uio_resid; - error = VOP_READ(vp, uio, (fp->f_flag & FNONBLOCK) ? IO_NDELAY : 0, - cred); + flag = 0; + if (fp->f_flag & FNONBLOCK) + flag |= IO_NDELAY; + + /* + * Sequential read heuristic. + * If we have been doing sequential input, + * a rewind operation doesn't turn off + * sequential input mode. + */ + if (((fp->f_offset == 0) && (fp->f_seqcount > 0)) || + (fp->f_offset == fp->f_nextread)) { + int tmpseq = fp->f_seqcount; + /* + * XXX we assume that the filesystem block size is + * the default. Not true, but still gives us a pretty + * good indicator of how sequential the read operations + * are. + */ + tmpseq += ((count + BKVASIZE - 1) / BKVASIZE); + if (tmpseq >= CHAR_MAX) + tmpseq = CHAR_MAX; + fp->f_seqcount = tmpseq; + flag |= (fp->f_seqcount << 16); + } else { + if (fp->f_seqcount > 1) + fp->f_seqcount = 1; + else + fp->f_seqcount = 0; + } + + error = VOP_READ(vp, uio, flag, cred); fp->f_offset += count - uio->uio_resid; + fp->f_nextread = fp->f_offset; VOP_UNLOCK(vp); return (error); } diff --git a/sys/sys/bio.h b/sys/sys/bio.h index ee7d213..5581aca 100644 --- a/sys/sys/bio.h +++ b/sys/sys/bio.h @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)buf.h 8.9 (Berkeley) 3/30/95 - * $Id: buf.h,v 1.34 1996/10/13 14:36:37 phk Exp $ + * $Id: buf.h,v 1.35 1996/11/30 22:41:35 dyson Exp $ */ #ifndef _SYS_BUF_H_ @@ -82,7 +82,6 @@ struct buf { } b_un; caddr_t b_kvabase; /* base kva for buffer */ int b_kvasize; /* size of kva for buffer */ - void *b_saveaddr; /* Original b_addr for physio. */ daddr_t b_lblkno; /* Logical block number. */ daddr_t b_blkno; /* Underlying physical block number. */ /* Function to call upon completion. */ @@ -97,6 +96,7 @@ struct buf { int b_validoff; /* Offset in buffer of valid region. */ int b_validend; /* Offset of end of valid region. */ daddr_t b_pblkno; /* physical block number */ + void *b_saveaddr; /* Original b_addr for physio. */ caddr_t b_savekva; /* saved kva for transfer while bouncing */ void *b_driver1; /* for private use by the driver */ void *b_driver2; /* for private use by the driver */ @@ -144,6 +144,7 @@ struct buf { #define B_XXX 0x02000000 /* Debugging flag. */ #define B_PAGING 0x04000000 /* volatile paging I/O -- bypass VMIO */ #define B_ORDERED 0x08000000 /* Must guarantee I/O ordering */ +#define B_RAM 0x10000000 /* Read ahead mark (flag) */ #define B_VMIO 0x20000000 /* VMIO flag */ #define B_CLUSTER 0x40000000 /* pagein op, so swap() can count it */ #define B_BOUNCE 0x80000000 /* bounce buffer flag */ @@ -220,7 +221,7 @@ void biodone __P((struct buf *)); void cluster_callback __P((struct buf *)); int cluster_read __P((struct vnode *, u_quad_t, daddr_t, long, - struct ucred *, struct buf **)); + struct ucred *, long, int, struct buf **)); int cluster_wbuild __P((struct vnode *, long, daddr_t, int)); void cluster_write __P((struct buf *, u_quad_t)); int physio __P((void (*)(struct buf *), struct buf *, dev_t, diff --git a/sys/sys/buf.h b/sys/sys/buf.h index ee7d213..5581aca 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)buf.h 8.9 (Berkeley) 3/30/95 - * $Id: buf.h,v 1.34 1996/10/13 14:36:37 phk Exp $ + * $Id: buf.h,v 1.35 1996/11/30 22:41:35 dyson Exp $ */ #ifndef _SYS_BUF_H_ @@ -82,7 +82,6 @@ struct buf { } b_un; caddr_t b_kvabase; /* base kva for buffer */ int b_kvasize; /* size of kva for buffer */ - void *b_saveaddr; /* Original b_addr for physio. */ daddr_t b_lblkno; /* Logical block number. */ daddr_t b_blkno; /* Underlying physical block number. */ /* Function to call upon completion. */ @@ -97,6 +96,7 @@ struct buf { int b_validoff; /* Offset in buffer of valid region. */ int b_validend; /* Offset of end of valid region. */ daddr_t b_pblkno; /* physical block number */ + void *b_saveaddr; /* Original b_addr for physio. */ caddr_t b_savekva; /* saved kva for transfer while bouncing */ void *b_driver1; /* for private use by the driver */ void *b_driver2; /* for private use by the driver */ @@ -144,6 +144,7 @@ struct buf { #define B_XXX 0x02000000 /* Debugging flag. */ #define B_PAGING 0x04000000 /* volatile paging I/O -- bypass VMIO */ #define B_ORDERED 0x08000000 /* Must guarantee I/O ordering */ +#define B_RAM 0x10000000 /* Read ahead mark (flag) */ #define B_VMIO 0x20000000 /* VMIO flag */ #define B_CLUSTER 0x40000000 /* pagein op, so swap() can count it */ #define B_BOUNCE 0x80000000 /* bounce buffer flag */ @@ -220,7 +221,7 @@ void biodone __P((struct buf *)); void cluster_callback __P((struct buf *)); int cluster_read __P((struct vnode *, u_quad_t, daddr_t, long, - struct ucred *, struct buf **)); + struct ucred *, long, int, struct buf **)); int cluster_wbuild __P((struct vnode *, long, daddr_t, int)); void cluster_write __P((struct buf *, u_quad_t)); int physio __P((void (*)(struct buf *), struct buf *, dev_t, diff --git a/sys/sys/file.h b/sys/sys/file.h index 34aa794..fe34f4c 100644 --- a/sys/sys/file.h +++ b/sys/sys/file.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)file.h 8.3 (Berkeley) 1/9/95 - * $Id: file.h,v 1.8 1996/09/03 14:25:10 bde Exp $ + * $Id: file.h,v 1.9 1996/12/19 19:42:26 bde Exp $ */ #ifndef _SYS_FILE_H_ @@ -74,6 +74,13 @@ struct file { struct proc *p)); int (*fo_close) __P((struct file *fp, struct proc *p)); } *f_ops; + int f_seqcount; /* + * count of sequential accesses -- cleared + * by most seek operations. + */ + off_t f_nextread; /* + * offset of next expected read + */ off_t f_offset; caddr_t f_data; /* vnode or socket */ }; diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index 7bd4578..324071c 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)filedesc.h 8.1 (Berkeley) 6/2/93 - * $Id: filedesc.h,v 1.7 1995/11/04 10:35:17 bde Exp $ + * $Id: filedesc.h,v 1.8 1996/02/23 18:49:21 peter Exp $ */ #ifndef _SYS_FILEDESC_H_ @@ -107,6 +107,8 @@ void fdfree __P((struct proc *p)); int closef __P((struct file *fp,struct proc *p)); void fdcloseexec __P((struct proc *p)); int getvnode __P((struct filedesc *fdp, int fd, struct file **fpp)); +int fdissequential __P((struct file *)); +void fdsequential __P((struct file *, int)); #endif #endif diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index fdf0b9a..19e88ac 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)vnode.h 8.7 (Berkeley) 2/4/94 - * $Id: vnode.h,v 1.35 1996/10/15 19:22:46 bde Exp $ + * $Id: vnode.h,v 1.36 1996/10/17 17:12:04 jkh Exp $ */ #ifndef _SYS_VNODE_H_ @@ -96,9 +96,7 @@ struct vnode { daddr_t v_cstart; /* start block of cluster */ daddr_t v_lasta; /* last allocation */ int v_clen; /* length of current cluster */ - int v_ralen; /* Read-ahead length */ int v_usage; /* Vnode usage counter */ - daddr_t v_maxra; /* last readahead block */ struct vm_object *v_object; /* Place to store VM object */ enum vtagtype v_tag; /* type of underlying data */ void *v_data; /* private data for fs */ diff --git a/sys/ufs/ufs/ufs_readwrite.c b/sys/ufs/ufs/ufs_readwrite.c index d5818ac..5cccabd 100644 --- a/sys/ufs/ufs/ufs_readwrite.c +++ b/sys/ufs/ufs/ufs_readwrite.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ufs_readwrite.c 8.7 (Berkeley) 1/21/94 - * $Id: ufs_readwrite.c,v 1.22 1996/09/03 07:09:11 davidg Exp $ + * $Id: ufs_readwrite.c,v 1.23 1996/12/11 05:17:23 dyson Exp $ */ #ifdef LFS_READWRITE @@ -80,8 +80,10 @@ READ(ap) long size, xfersize, blkoffset; int error; u_short mode; + int seqcount; vp = ap->a_vp; + seqcount = ap->a_ioflag >> 16; ip = VTOI(vp); mode = ip->i_mode; uio = ap->a_uio; @@ -116,13 +118,14 @@ READ(ap) #ifdef LFS_READWRITE (void)lfs_check(vp, lbn); - error = cluster_read(vp, ip->i_size, lbn, size, NOCRED, &bp); + error = cluster_read(vp, ip->i_size, lbn, + size, NOCRED, uio->uio_resid, seqcount, &bp); #else if (lblktosize(fs, nextlbn) >= ip->i_size) error = bread(vp, lbn, size, NOCRED, &bp); else if (doclusterread) - error = cluster_read(vp, - ip->i_size, lbn, size, NOCRED, &bp); + error = cluster_read(vp, ip->i_size, lbn, + size, NOCRED, uio->uio_resid, seqcount, &bp); else if (lbn - 1 == vp->v_lastr) { int nextsize = BLKSIZE(fs, ip, nextlbn); error = breadn(vp, lbn, @@ -361,6 +364,7 @@ ffs_getpages(ap) } obj = ap->a_m[ap->a_reqpage]->object; + bsize = ap->a_vp->v_mount->mnt_stat.f_iosize; if (obj->behavior == OBJ_SEQUENTIAL) { struct uio auio; @@ -387,7 +391,8 @@ ffs_getpages(ap) auio.uio_segflg = UIO_NOCOPY; auio.uio_rw = UIO_READ; auio.uio_procp = curproc; - error = VOP_READ(ap->a_vp, &auio, 0, curproc->p_ucred); + error = VOP_READ(ap->a_vp, &auio, + ((MAXBSIZE / bsize) << 16), curproc->p_ucred); m->flags |= PG_BUSY; m->busy--; @@ -397,9 +402,6 @@ ffs_getpages(ap) return 0; } - - bsize = ap->a_vp->v_mount->mnt_stat.f_iosize; - /* * foff is the file offset of the required page * reqlblkno is the logical block that contains the page |