Date: Sat, 16 Jul 2011 10:42:52 +0000 From: gk@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r224303 - soc2011/gk/ino64-head/sys/ufs/ffs Message-ID: <20110716104252.47243106564A@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
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,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20110716104252.47243106564A>