Hi, Were we not intending to make this turn itself off in cases where it produces no benefit? I thought the plan was to track the state via the file descriptor in order to avoid readingahead the same blocks over and over again too,
Steve. On Tue, 2011-10-04 at 12:39 -0400, Bob Peterson wrote: > Hi, > > This patch adds read-ahead capability to GFS2's > directory hash table management. It greatly improves > performance for some directory operations. For example: > In one of my file systems that has 1000 directories, each > of which has 1000 files, time to execute a recursive > ls (time ls -fR /mnt/gfs2 > /dev/null) was reduced > from 2m2.814s on a stock kernel to 0m45.938s. > > Regards, > > Bob Peterson > Red Hat File Systems > > Signed-off-by: Bob Peterson <rpete...@redhat.com> > -- > fs/gfs2/dir.c | 33 +++++++++++++++++++++++++++++++++ > 1 files changed, 33 insertions(+), 0 deletions(-) > > diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c > index 2045d70..9b4262e 100644 > --- a/fs/gfs2/dir.c > +++ b/fs/gfs2/dir.c > @@ -1376,6 +1376,37 @@ out: > return error; > } > > +static void gfs2_dir_readahead(struct inode *inode, __be64 *ht, unsigned > hsize, > + u32 index) > +{ > + struct gfs2_inode *ip = GFS2_I(inode); > + struct gfs2_glock *gl = ip->i_gl; > + struct buffer_head *bh; > + u64 blocknr = 0, last; > + unsigned count = 0; > + > + while (index < hsize) { > + last = blocknr; > + blocknr = be64_to_cpu(ht[index++]); > + if (blocknr == last) > + continue; > + count++; > + if (count > 128) > + break; > + bh = gfs2_getbuf(gl, blocknr, 1); > + if (trylock_buffer(bh)) { > + if (buffer_uptodate(bh)) { > + unlock_buffer(bh); > + brelse(bh); > + continue; > + } > + bh->b_end_io = end_buffer_read_sync; > + submit_bh(READA | REQ_META, bh); > + continue; > + } > + brelse(bh); > + } > +} > > /** > * dir_e_read - Reads the entries from a directory into a filldir buffer > @@ -1406,6 +1437,8 @@ static int dir_e_read(struct inode *inode, u64 *offset, > void *opaque, > if (IS_ERR(lp)) > return PTR_ERR(lp); > > + gfs2_dir_readahead(inode, lp, hsize, index); > + > while (index < hsize) { > error = gfs2_dir_read_leaf(inode, offset, opaque, filldir, > &copied, &depth, >