summaryrefslogtreecommitdiff
path: root/fs/gfs2/meta_io.c
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2015-11-11 15:00:35 -0600
committerBob Peterson <rpeterso@redhat.com>2015-11-16 12:00:29 -0600
commitc8d577038449a718ad0027d1790b6ef4441715d4 (patch)
tree7ba2dd87040f008328b528e96ac99b88736188f7 /fs/gfs2/meta_io.c
parent3dd1dd8c696bdb7c8dcc9456cb23558ad1b336b8 (diff)
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.c27
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;