socsvn commit: r224303 - soc2011/gk/ino64-head/sys/ufs/ffs
gk at FreeBSD.org
gk at FreeBSD.org
Sat Jul 16 10:42:54 UTC 2011
Author: gk
Date: Sat Jul 16 10:42:52 2011
New Revision: 224303
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=224303
Log:
ufs: Extract code for read-ahead read into ffs_blkatoff_ra function
Modified:
soc2011/gk/ino64-head/sys/ufs/ffs/ffs_extern.h
soc2011/gk/ino64-head/sys/ufs/ffs/ffs_subr.c
soc2011/gk/ino64-head/sys/ufs/ffs/ffs_vnops.c
Modified: soc2011/gk/ino64-head/sys/ufs/ffs/ffs_extern.h
==============================================================================
--- soc2011/gk/ino64-head/sys/ufs/ffs/ffs_extern.h Sat Jul 16 09:20:22 2011 (r224302)
+++ soc2011/gk/ino64-head/sys/ufs/ffs/ffs_extern.h Sat Jul 16 10:42:52 2011 (r224303)
@@ -56,6 +56,7 @@
int ffs_balloc_ufs2(struct vnode *a_vp, off_t a_startoffset, int a_size,
struct ucred *a_cred, int a_flags, struct buf **a_bpp);
int ffs_blkatoff(struct vnode *, off_t, char **, struct buf **);
+int ffs_blkatoff_ra(struct vnode *, off_t, size_t, struct buf **, int);
void ffs_blkfree(struct ufsmount *, struct fs *, struct vnode *,
ufs2_daddr_t, long, ino_t, struct workhead *);
ufs2_daddr_t ffs_blkpref_ufs1(struct inode *, ufs_lbn_t, int, ufs1_daddr_t *);
Modified: soc2011/gk/ino64-head/sys/ufs/ffs/ffs_subr.c
==============================================================================
--- soc2011/gk/ino64-head/sys/ufs/ffs/ffs_subr.c Sat Jul 16 09:20:22 2011 (r224302)
+++ soc2011/gk/ino64-head/sys/ufs/ffs/ffs_subr.c Sat Jul 16 10:42:52 2011 (r224303)
@@ -94,6 +94,75 @@
return (0);
}
+int
+ffs_blkatoff_ra(struct vnode *vp, off_t uoffset, size_t nextread,
+ struct buf **bpp, int seqcount)
+{
+ struct inode *ip;
+ struct fs *fs;
+ struct buf *bp;
+ ufs_lbn_t lbn, nextlbn;
+ long size, blkoffset;
+ int error;
+
+ ip = VTOI(vp);
+ fs = ip->i_fs;
+ lbn = lblkno(fs, uoffset);
+ nextlbn = lbn + 1;
+
+ /*
+ * size of buffer. The buffer representing the
+ * end of the file is rounded up to the size of
+ * the block type ( fragment or full block,
+ * depending ).
+ */
+ size = blksize(fs, ip, lbn);
+ blkoffset = blkoff(fs, uoffset);
+
+ if (lblktosize(fs, nextlbn) >= ip->i_size) {
+ /*
+ * Don't do readahead if this is the end of the file.
+ */
+ error = bread(vp, lbn, size, NOCRED, &bp);
+ } else if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) {
+ /*
+ * Otherwise if we are allowed to cluster,
+ * grab as much as we can.
+ *
+ * XXX This may not be a win if we are not
+ * doing sequential access.
+ */
+ error = cluster_read(vp, ip->i_size, lbn,
+ size, NOCRED, blkoffset + nextread, seqcount, &bp);
+ } else if (seqcount > 1) {
+ /*
+ * If we are NOT allowed to cluster, then
+ * if we appear to be acting sequentially,
+ * fire off a request for a readahead
+ * as well as a read. Note that the 4th and 5th
+ * arguments point to arrays of the size specified in
+ * the 6th argument.
+ */
+ int nextsize = blksize(fs, ip, nextlbn);
+ error = breadn(vp, lbn,
+ size, &nextlbn, &nextsize, 1, NOCRED, &bp);
+ } else {
+ /*
+ * Failing all of the above, just read what the
+ * user asked for. Interestingly, the same as
+ * the first option above.
+ */
+ error = bread(vp, lbn, size, NOCRED, &bp);
+ }
+ if (error) {
+ brelse(bp);
+ bp = NULL;
+ return (error);
+ }
+ *bpp = bp;
+ return (0);
+}
+
/*
* Load up the contents of an inode and copy the appropriate pieces
* to the incore copy.
Modified: soc2011/gk/ino64-head/sys/ufs/ffs/ffs_vnops.c
==============================================================================
--- soc2011/gk/ino64-head/sys/ufs/ffs/ffs_vnops.c Sat Jul 16 09:20:22 2011 (r224302)
+++ soc2011/gk/ino64-head/sys/ufs/ffs/ffs_vnops.c Sat Jul 16 10:42:52 2011 (r224303)
@@ -436,9 +436,8 @@
struct uio *uio;
struct fs *fs;
struct buf *bp;
- ufs_lbn_t lbn, nextlbn;
off_t bytesinfile;
- long size, xfersize, blkoffset;
+ long xfersize, blkoffset;
int error, orig_resid;
int seqcount;
int ioflag;
@@ -488,16 +487,23 @@
for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) {
if ((bytesinfile = ip->i_size - uio->uio_offset) <= 0)
break;
- lbn = lblkno(fs, uio->uio_offset);
- nextlbn = lbn + 1;
+
+ error = ffs_blkatoff_ra(vp, uio->uio_offset, uio->uio_resid,
+ &bp, seqcount);
+ if (error) {
+ MPASS(bp == NULL);
+ break;
+ }
/*
- * size of buffer. The buffer representing the
- * end of the file is rounded up to the size of
- * the block type ( fragment or full block,
- * depending ).
+ * If IO_DIRECT then set B_DIRECT for the buffer. This
+ * will cause us to attempt to release the buffer later on
+ * and will cause the buffer cache to attempt to free the
+ * underlying pages.
*/
- size = blksize(fs, ip, lbn);
+ if (ioflag & IO_DIRECT)
+ bp->b_flags |= B_DIRECT;
+
blkoffset = blkoff(fs, uio->uio_offset);
/*
@@ -505,7 +511,7 @@
* one FS block less the amount of the data before
* our startpoint (duh!)
*/
- xfersize = fs->fs_bsize - blkoffset;
+ xfersize = bp->b_bufsize - blkoffset;
/*
* But if we actually want less than the block,
@@ -517,56 +523,6 @@
if (bytesinfile < xfersize)
xfersize = bytesinfile;
- if (lblktosize(fs, nextlbn) >= ip->i_size) {
- /*
- * Don't do readahead if this is the end of the file.
- */
- error = bread(vp, lbn, size, NOCRED, &bp);
- } else if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERR) == 0) {
- /*
- * Otherwise if we are allowed to cluster,
- * grab as much as we can.
- *
- * XXX This may not be a win if we are not
- * doing sequential access.
- */
- error = cluster_read(vp, ip->i_size, lbn,
- size, NOCRED, blkoffset + uio->uio_resid, seqcount, &bp);
- } else if (seqcount > 1) {
- /*
- * If we are NOT allowed to cluster, then
- * if we appear to be acting sequentially,
- * fire off a request for a readahead
- * as well as a read. Note that the 4th and 5th
- * arguments point to arrays of the size specified in
- * the 6th argument.
- */
- int nextsize = blksize(fs, ip, nextlbn);
- error = breadn(vp, lbn,
- size, &nextlbn, &nextsize, 1, NOCRED, &bp);
- } else {
- /*
- * Failing all of the above, just read what the
- * user asked for. Interestingly, the same as
- * the first option above.
- */
- error = bread(vp, lbn, size, NOCRED, &bp);
- }
- if (error) {
- brelse(bp);
- bp = NULL;
- break;
- }
-
- /*
- * If IO_DIRECT then set B_DIRECT for the buffer. This
- * will cause us to attempt to release the buffer later on
- * and will cause the buffer cache to attempt to free the
- * underlying pages.
- */
- if (ioflag & IO_DIRECT)
- bp->b_flags |= B_DIRECT;
-
/*
* We should only get non-zero b_resid when an I/O error
* has occurred, which should cause us to break above.
@@ -574,11 +530,10 @@
* then we want to ensure that we do not uiomove bad
* or uninitialized data.
*/
- size -= bp->b_resid;
- if (size < xfersize) {
- if (size == 0)
+ if (bp->b_bufsize - bp->b_resid < xfersize) {
+ if (bp->b_bufsize == bp->b_resid)
break;
- xfersize = size;
+ xfersize = bp->b_bufsize - bp->b_resid;
}
error = uiomove((char *)bp->b_data + blkoffset,
More information about the svn-soc-all
mailing list