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,