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