提交 c8d57703 编写于 作者: A Andreas Gruenbacher 提交者: Bob Peterson

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: NAndreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: NBob Peterson <rpeterso@redhat.com>
上级 3dd1dd8c
...@@ -108,7 +108,7 @@ static int gfs2_dir_get_existing_buffer(struct gfs2_inode *ip, u64 block, ...@@ -108,7 +108,7 @@ static int gfs2_dir_get_existing_buffer(struct gfs2_inode *ip, u64 block,
struct buffer_head *bh; struct buffer_head *bh;
int error; 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) if (error)
return error; return error;
if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_JD)) { if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_JD)) {
...@@ -305,7 +305,7 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, __be64 *buf, ...@@ -305,7 +305,7 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, __be64 *buf,
BUG_ON(extlen < 1); BUG_ON(extlen < 1);
bh = gfs2_meta_ra(ip->i_gl, dblock, extlen); bh = gfs2_meta_ra(ip->i_gl, dblock, extlen);
} else { } 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) if (error)
goto fail; goto fail;
} }
...@@ -723,7 +723,7 @@ static int get_leaf(struct gfs2_inode *dip, u64 leaf_no, ...@@ -723,7 +723,7 @@ static int get_leaf(struct gfs2_inode *dip, u64 leaf_no,
{ {
int error; 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)) { if (!error && gfs2_metatype_check(GFS2_SB(&dip->i_inode), *bhp, GFS2_METATYPE_LF)) {
/* pr_info("block num=%llu\n", leaf_no); */ /* pr_info("block num=%llu\n", leaf_no); */
error = -EIO; error = -EIO;
...@@ -1560,15 +1560,22 @@ struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name, ...@@ -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); dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
if (dent) { if (dent) {
struct inode *inode;
u16 rahead;
if (IS_ERR(dent)) if (IS_ERR(dent))
return ERR_CAST(dent); return ERR_CAST(dent);
dtype = be16_to_cpu(dent->de_type); dtype = be16_to_cpu(dent->de_type);
rahead = be16_to_cpu(dent->de_rahead);
addr = be64_to_cpu(dent->de_inum.no_addr); addr = be64_to_cpu(dent->de_inum.no_addr);
formal_ino = be64_to_cpu(dent->de_inum.no_formal_ino); formal_ino = be64_to_cpu(dent->de_inum.no_formal_ino);
brelse(bh); brelse(bh);
if (fail_on_exist) if (fail_on_exist)
return ERR_PTR(-EEXIST); 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); return ERR_PTR(-ENOENT);
} }
......
...@@ -402,6 +402,7 @@ struct gfs2_inode { ...@@ -402,6 +402,7 @@ struct gfs2_inode {
u32 i_diskflags; u32 i_diskflags;
u8 i_height; u8 i_height;
u8 i_depth; u8 i_depth;
u16 i_rahead;
}; };
/* /*
......
...@@ -187,6 +187,21 @@ struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) ...@@ -187,6 +187,21 @@ struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno)
return bh; 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 * gfs2_meta_read - Read a block from disk
* @gl: The glock covering the block * @gl: The glock covering the block
...@@ -198,7 +213,7 @@ struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno) ...@@ -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, 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 gfs2_sbd *sdp = gl->gl_name.ln_sbd;
struct buffer_head *bh; struct buffer_head *bh;
...@@ -213,11 +228,15 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, ...@@ -213,11 +228,15 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
lock_buffer(bh); lock_buffer(bh);
if (buffer_uptodate(bh)) { if (buffer_uptodate(bh)) {
unlock_buffer(bh); unlock_buffer(bh);
if (rahead)
gfs2_meta_readahead(gl, blkno + 1);
return 0; return 0;
} }
bh->b_end_io = end_buffer_read_sync; bh->b_end_io = end_buffer_read_sync;
get_bh(bh); get_bh(bh);
submit_bh(READ_SYNC | REQ_META | REQ_PRIO, bh); submit_bh(READ_SYNC | REQ_META | REQ_PRIO, bh);
if (rahead)
gfs2_meta_readahead(gl, blkno + 1);
if (!(flags & DIO_WAIT)) if (!(flags & DIO_WAIT))
return 0; return 0;
...@@ -341,8 +360,12 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num, ...@@ -341,8 +360,12 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
struct buffer_head *bh; struct buffer_head *bh;
int ret = 0; int ret = 0;
u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI; 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)) { if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) {
brelse(bh); brelse(bh);
ret = -EIO; ret = -EIO;
......
...@@ -53,7 +53,7 @@ static inline struct gfs2_sbd *gfs2_mapping2sbd(struct address_space *mapping) ...@@ -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 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, 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 int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh);
extern struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, extern struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno,
int create); int create);
......
...@@ -388,7 +388,7 @@ static int bh_get(struct gfs2_quota_data *qd) ...@@ -388,7 +388,7 @@ static int bh_get(struct gfs2_quota_data *qd)
error = gfs2_block_map(&ip->i_inode, block, &bh_map, 0); error = gfs2_block_map(&ip->i_inode, block, &bh_map, 0);
if (error) if (error)
goto fail; 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) if (error)
goto fail; goto fail;
error = -EIO; error = -EIO;
......
...@@ -1158,7 +1158,7 @@ static int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) ...@@ -1158,7 +1158,7 @@ static int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
for (x = 0; x < length; x++) { for (x = 0; x < length; x++) {
bi = rgd->rd_bits + 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) if (error)
goto fail; goto fail;
} }
......
...@@ -1633,6 +1633,7 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb) ...@@ -1633,6 +1633,7 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb)
ip->i_gl = NULL; ip->i_gl = NULL;
ip->i_rgd = NULL; ip->i_rgd = NULL;
ip->i_res = NULL; ip->i_res = NULL;
ip->i_rahead = 0;
} }
return &ip->i_inode; return &ip->i_inode;
} }
......
...@@ -119,7 +119,7 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data) ...@@ -119,7 +119,7 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
__be64 *eablk, *end; __be64 *eablk, *end;
int error; 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) if (error)
return error; return error;
...@@ -143,7 +143,7 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data) ...@@ -143,7 +143,7 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
break; break;
bn = be64_to_cpu(*eablk); 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) if (error)
break; break;
error = ea_foreach_i(ip, eabh, ea_call, data); error = ea_foreach_i(ip, eabh, ea_call, data);
...@@ -477,7 +477,7 @@ static int gfs2_iter_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea, ...@@ -477,7 +477,7 @@ static int gfs2_iter_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
return -ENOMEM; return -ENOMEM;
for (x = 0; x < nptrs; x++) { 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); bh + x);
if (error) { if (error) {
while (x--) while (x--)
...@@ -977,7 +977,7 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er, ...@@ -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) { if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
__be64 *end; __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); &indbh);
if (error) if (error)
return error; return error;
...@@ -1303,7 +1303,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip) ...@@ -1303,7 +1303,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
memset(&rlist, 0, sizeof(struct gfs2_rgrp_list)); 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) if (error)
return error; return error;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册