Skip to content

Commit

Permalink
gfs2: Extended attribute readahead
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Andreas Gruenbacher authored and Bob Peterson committed Nov 16, 2015
1 parent 3dd1dd8 commit c8d5770
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 14 deletions.
15 changes: 11 additions & 4 deletions fs/gfs2/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ static int gfs2_dir_get_existing_buffer(struct gfs2_inode *ip, u64 block,
struct buffer_head *bh;
int error;

error = gfs2_meta_read(ip->i_gl, block, DIO_WAIT, &bh);
error = gfs2_meta_read(ip->i_gl, block, DIO_WAIT, 0, &bh);
if (error)
return error;
if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_JD)) {
Expand Down Expand Up @@ -305,7 +305,7 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, __be64 *buf,
BUG_ON(extlen < 1);
bh = gfs2_meta_ra(ip->i_gl, dblock, extlen);
} else {
error = gfs2_meta_read(ip->i_gl, dblock, DIO_WAIT, &bh);
error = gfs2_meta_read(ip->i_gl, dblock, DIO_WAIT, 0, &bh);
if (error)
goto fail;
}
Expand Down Expand Up @@ -723,7 +723,7 @@ static int get_leaf(struct gfs2_inode *dip, u64 leaf_no,
{
int error;

error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_WAIT, bhp);
error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_WAIT, 0, bhp);
if (!error && gfs2_metatype_check(GFS2_SB(&dip->i_inode), *bhp, GFS2_METATYPE_LF)) {
/* pr_info("block num=%llu\n", leaf_no); */
error = -EIO;
Expand Down Expand Up @@ -1560,15 +1560,22 @@ struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name,

dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
if (dent) {
struct inode *inode;
u16 rahead;

if (IS_ERR(dent))
return ERR_CAST(dent);
dtype = be16_to_cpu(dent->de_type);
rahead = be16_to_cpu(dent->de_rahead);
addr = be64_to_cpu(dent->de_inum.no_addr);
formal_ino = be64_to_cpu(dent->de_inum.no_formal_ino);
brelse(bh);
if (fail_on_exist)
return ERR_PTR(-EEXIST);
return gfs2_inode_lookup(dir->i_sb, dtype, addr, formal_ino, 0);
inode = gfs2_inode_lookup(dir->i_sb, dtype, addr, formal_ino, 0);
if (!IS_ERR(inode))
GFS2_I(inode)->i_rahead = rahead;
return inode;
}
return ERR_PTR(-ENOENT);
}
Expand Down
1 change: 1 addition & 0 deletions fs/gfs2/incore.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ struct gfs2_inode {
u32 i_diskflags;
u8 i_height;
u8 i_depth;
u16 i_rahead;
};

/*
Expand Down
27 changes: 25 additions & 2 deletions fs/gfs2/meta_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion fs/gfs2/meta_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ static inline struct gfs2_sbd *gfs2_mapping2sbd(struct address_space *mapping)

extern struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno);
extern int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
struct buffer_head **bhp);
int rahead, struct buffer_head **bhp);
extern int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh);
extern struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno,
int create);
Expand Down
2 changes: 1 addition & 1 deletion fs/gfs2/quota.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ static int bh_get(struct gfs2_quota_data *qd)
error = gfs2_block_map(&ip->i_inode, block, &bh_map, 0);
if (error)
goto fail;
error = gfs2_meta_read(ip->i_gl, bh_map.b_blocknr, DIO_WAIT, &bh);
error = gfs2_meta_read(ip->i_gl, bh_map.b_blocknr, DIO_WAIT, 0, &bh);
if (error)
goto fail;
error = -EIO;
Expand Down
2 changes: 1 addition & 1 deletion fs/gfs2/rgrp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1158,7 +1158,7 @@ static int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)

for (x = 0; x < length; x++) {
bi = rgd->rd_bits + x;
error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, &bi->bi_bh);
error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, 0, &bi->bi_bh);
if (error)
goto fail;
}
Expand Down
1 change: 1 addition & 0 deletions fs/gfs2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1633,6 +1633,7 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb)
ip->i_gl = NULL;
ip->i_rgd = NULL;
ip->i_res = NULL;
ip->i_rahead = 0;
}
return &ip->i_inode;
}
Expand Down
10 changes: 5 additions & 5 deletions fs/gfs2/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
__be64 *eablk, *end;
int error;

error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &bh);
error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, 0, &bh);
if (error)
return error;

Expand All @@ -143,7 +143,7 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
break;
bn = be64_to_cpu(*eablk);

error = gfs2_meta_read(ip->i_gl, bn, DIO_WAIT, &eabh);
error = gfs2_meta_read(ip->i_gl, bn, DIO_WAIT, 0, &eabh);
if (error)
break;
error = ea_foreach_i(ip, eabh, ea_call, data);
Expand Down Expand Up @@ -477,7 +477,7 @@ static int gfs2_iter_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
return -ENOMEM;

for (x = 0; x < nptrs; x++) {
error = gfs2_meta_read(ip->i_gl, be64_to_cpu(*dataptrs), 0,
error = gfs2_meta_read(ip->i_gl, be64_to_cpu(*dataptrs), 0, 0,
bh + x);
if (error) {
while (x--)
Expand Down Expand Up @@ -977,7 +977,7 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er,
if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
__be64 *end;

error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT,
error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, 0,
&indbh);
if (error)
return error;
Expand Down Expand Up @@ -1303,7 +1303,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)

memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));

error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &indbh);
error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, 0, &indbh);
if (error)
return error;

Expand Down

0 comments on commit c8d5770

Please sign in to comment.