diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2015-11-12 00:00:35 +0300 |
---|---|---|
committer | Bob Peterson <rpeterso@redhat.com> | 2015-11-16 21:00:29 +0300 |
commit | c8d577038449a718ad0027d1790b6ef4441715d4 (patch) | |
tree | 7ba2dd87040f008328b528e96ac99b88736188f7 /fs/gfs2/meta_io.c | |
parent | 3dd1dd8c696bdb7c8dcc9456cb23558ad1b336b8 (diff) | |
download | linux-c8d577038449a718ad0027d1790b6ef4441715d4.tar.xz |
gfs2: Extended attribute readahead
When gfs2 allocates an inode and its extended attribute block next to
each other at inode create time, the inode's directory entry indicates
that in de_rahead. In that case, we can readahead the extended
attribute block when we read in the inode.
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Diffstat (limited to 'fs/gfs2/meta_io.c')
-rw-r--r-- | fs/gfs2/meta_io.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 0e1d4be5865a..0f24828f8488 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c @@ -187,6 +187,21 @@ struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) return bh; } +static void gfs2_meta_readahead(struct gfs2_glock *gl, u64 blkno) +{ + struct buffer_head *bh; + + bh = gfs2_getbuf(gl, blkno, 1); + lock_buffer(bh); + if (buffer_uptodate(bh)) { + unlock_buffer(bh); + brelse(bh); + return; + } + bh->b_end_io = end_buffer_read_sync; + submit_bh(READA | REQ_META | REQ_PRIO, bh); +} + /** * gfs2_meta_read - Read a block from disk * @gl: The glock covering the block @@ -198,7 +213,7 @@ struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) */ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, - struct buffer_head **bhp) + int rahead, struct buffer_head **bhp) { struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; struct buffer_head *bh; @@ -213,11 +228,15 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, lock_buffer(bh); if (buffer_uptodate(bh)) { unlock_buffer(bh); + if (rahead) + gfs2_meta_readahead(gl, blkno + 1); return 0; } bh->b_end_io = end_buffer_read_sync; get_bh(bh); submit_bh(READ_SYNC | REQ_META | REQ_PRIO, bh); + if (rahead) + gfs2_meta_readahead(gl, blkno + 1); if (!(flags & DIO_WAIT)) return 0; @@ -341,8 +360,12 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, struct buffer_head *bh; int ret = 0; u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI; + int rahead = 0; + + if (num == ip->i_no_addr) + rahead = ip->i_rahead; - ret = gfs2_meta_read(gl, num, DIO_WAIT, &bh); + ret = gfs2_meta_read(gl, num, DIO_WAIT, rahead, &bh); if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) { brelse(bh); ret = -EIO; |