aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2015-11-11 16:00:35 -0500
committerBob Peterson <rpeterso@redhat.com>2015-11-16 13:00:29 -0500
commitc8d577038449a718ad0027d1790b6ef4441715d4 (patch)
tree7ba2dd87040f008328b528e96ac99b88736188f7
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>
-rw-r--r--fs/gfs2/dir.c15
-rw-r--r--fs/gfs2/incore.h1
-rw-r--r--fs/gfs2/meta_io.c27
-rw-r--r--fs/gfs2/meta_io.h2
-rw-r--r--fs/gfs2/quota.c2
-rw-r--r--fs/gfs2/rgrp.c2
-rw-r--r--fs/gfs2/super.c1
-rw-r--r--fs/gfs2/xattr.c10
8 files changed, 46 insertions, 14 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index ad8a5b757cc7..c2486598fb87 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -108,7 +108,7 @@ static int gfs2_dir_get_existing_buffer(struct gfs2_inode *ip, u64 block,
108 struct buffer_head *bh; 108 struct buffer_head *bh;
109 int error; 109 int error;
110 110
111 error = gfs2_meta_read(ip->i_gl, block, DIO_WAIT, &bh); 111 error = gfs2_meta_read(ip->i_gl, block, DIO_WAIT, 0, &bh);
112 if (error) 112 if (error)
113 return error; 113 return error;
114 if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_JD)) { 114 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 BUG_ON(extlen < 1); 305 BUG_ON(extlen < 1);
306 bh = gfs2_meta_ra(ip->i_gl, dblock, extlen); 306 bh = gfs2_meta_ra(ip->i_gl, dblock, extlen);
307 } else { 307 } else {
308 error = gfs2_meta_read(ip->i_gl, dblock, DIO_WAIT, &bh); 308 error = gfs2_meta_read(ip->i_gl, dblock, DIO_WAIT, 0, &bh);
309 if (error) 309 if (error)
310 goto fail; 310 goto fail;
311 } 311 }
@@ -723,7 +723,7 @@ static int get_leaf(struct gfs2_inode *dip, u64 leaf_no,
723{ 723{
724 int error; 724 int error;
725 725
726 error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_WAIT, bhp); 726 error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_WAIT, 0, bhp);
727 if (!error && gfs2_metatype_check(GFS2_SB(&dip->i_inode), *bhp, GFS2_METATYPE_LF)) { 727 if (!error && gfs2_metatype_check(GFS2_SB(&dip->i_inode), *bhp, GFS2_METATYPE_LF)) {
728 /* pr_info("block num=%llu\n", leaf_no); */ 728 /* pr_info("block num=%llu\n", leaf_no); */
729 error = -EIO; 729 error = -EIO;
@@ -1560,15 +1560,22 @@ struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name,
1560 1560
1561 dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); 1561 dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
1562 if (dent) { 1562 if (dent) {
1563 struct inode *inode;
1564 u16 rahead;
1565
1563 if (IS_ERR(dent)) 1566 if (IS_ERR(dent))
1564 return ERR_CAST(dent); 1567 return ERR_CAST(dent);
1565 dtype = be16_to_cpu(dent->de_type); 1568 dtype = be16_to_cpu(dent->de_type);
1569 rahead = be16_to_cpu(dent->de_rahead);
1566 addr = be64_to_cpu(dent->de_inum.no_addr); 1570 addr = be64_to_cpu(dent->de_inum.no_addr);
1567 formal_ino = be64_to_cpu(dent->de_inum.no_formal_ino); 1571 formal_ino = be64_to_cpu(dent->de_inum.no_formal_ino);
1568 brelse(bh); 1572 brelse(bh);
1569 if (fail_on_exist) 1573 if (fail_on_exist)
1570 return ERR_PTR(-EEXIST); 1574 return ERR_PTR(-EEXIST);
1571 return gfs2_inode_lookup(dir->i_sb, dtype, addr, formal_ino, 0); 1575 inode = gfs2_inode_lookup(dir->i_sb, dtype, addr, formal_ino, 0);
1576 if (!IS_ERR(inode))
1577 GFS2_I(inode)->i_rahead = rahead;
1578 return inode;
1572 } 1579 }
1573 return ERR_PTR(-ENOENT); 1580 return ERR_PTR(-ENOENT);
1574} 1581}
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index de7b4f97ac75..77e778496903 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -402,6 +402,7 @@ struct gfs2_inode {
402 u32 i_diskflags; 402 u32 i_diskflags;
403 u8 i_height; 403 u8 i_height;
404 u8 i_depth; 404 u8 i_depth;
405 u16 i_rahead;
405}; 406};
406 407
407/* 408/*
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)
187 return bh; 187 return bh;
188} 188}
189 189
190static void gfs2_meta_readahead(struct gfs2_glock *gl, u64 blkno)
191{
192 struct buffer_head *bh;
193
194 bh = gfs2_getbuf(gl, blkno, 1);
195 lock_buffer(bh);
196 if (buffer_uptodate(bh)) {
197 unlock_buffer(bh);
198 brelse(bh);
199 return;
200 }
201 bh->b_end_io = end_buffer_read_sync;
202 submit_bh(READA | REQ_META | REQ_PRIO, bh);
203}
204
190/** 205/**
191 * gfs2_meta_read - Read a block from disk 206 * gfs2_meta_read - Read a block from disk
192 * @gl: The glock covering the block 207 * @gl: The glock covering the block
@@ -198,7 +213,7 @@ struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno)
198 */ 213 */
199 214
200int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, 215int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
201 struct buffer_head **bhp) 216 int rahead, struct buffer_head **bhp)
202{ 217{
203 struct gfs2_sbd *sdp = gl->gl_name.ln_sbd; 218 struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
204 struct buffer_head *bh; 219 struct buffer_head *bh;
@@ -213,11 +228,15 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
213 lock_buffer(bh); 228 lock_buffer(bh);
214 if (buffer_uptodate(bh)) { 229 if (buffer_uptodate(bh)) {
215 unlock_buffer(bh); 230 unlock_buffer(bh);
231 if (rahead)
232 gfs2_meta_readahead(gl, blkno + 1);
216 return 0; 233 return 0;
217 } 234 }
218 bh->b_end_io = end_buffer_read_sync; 235 bh->b_end_io = end_buffer_read_sync;
219 get_bh(bh); 236 get_bh(bh);
220 submit_bh(READ_SYNC | REQ_META | REQ_PRIO, bh); 237 submit_bh(READ_SYNC | REQ_META | REQ_PRIO, bh);
238 if (rahead)
239 gfs2_meta_readahead(gl, blkno + 1);
221 if (!(flags & DIO_WAIT)) 240 if (!(flags & DIO_WAIT))
222 return 0; 241 return 0;
223 242
@@ -341,8 +360,12 @@ int gfs2_meta_indirect_buffer(struct gfs2_inode *ip, int height, u64 num,
341 struct buffer_head *bh; 360 struct buffer_head *bh;
342 int ret = 0; 361 int ret = 0;
343 u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI; 362 u32 mtype = height ? GFS2_METATYPE_IN : GFS2_METATYPE_DI;
363 int rahead = 0;
364
365 if (num == ip->i_no_addr)
366 rahead = ip->i_rahead;
344 367
345 ret = gfs2_meta_read(gl, num, DIO_WAIT, &bh); 368 ret = gfs2_meta_read(gl, num, DIO_WAIT, rahead, &bh);
346 if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) { 369 if (ret == 0 && gfs2_metatype_check(sdp, bh, mtype)) {
347 brelse(bh); 370 brelse(bh);
348 ret = -EIO; 371 ret = -EIO;
diff --git a/fs/gfs2/meta_io.h b/fs/gfs2/meta_io.h
index 8ca161567a93..c5086c8af5ed 100644
--- a/fs/gfs2/meta_io.h
+++ b/fs/gfs2/meta_io.h
@@ -53,7 +53,7 @@ static inline struct gfs2_sbd *gfs2_mapping2sbd(struct address_space *mapping)
53 53
54extern struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno); 54extern struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno);
55extern int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, 55extern int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
56 struct buffer_head **bhp); 56 int rahead, struct buffer_head **bhp);
57extern int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh); 57extern int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh);
58extern struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, 58extern struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno,
59 int create); 59 int create);
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 3a31226531ea..e01298d922c0 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -388,7 +388,7 @@ static int bh_get(struct gfs2_quota_data *qd)
388 error = gfs2_block_map(&ip->i_inode, block, &bh_map, 0); 388 error = gfs2_block_map(&ip->i_inode, block, &bh_map, 0);
389 if (error) 389 if (error)
390 goto fail; 390 goto fail;
391 error = gfs2_meta_read(ip->i_gl, bh_map.b_blocknr, DIO_WAIT, &bh); 391 error = gfs2_meta_read(ip->i_gl, bh_map.b_blocknr, DIO_WAIT, 0, &bh);
392 if (error) 392 if (error)
393 goto fail; 393 goto fail;
394 error = -EIO; 394 error = -EIO;
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index c134c0462cee..ac0a65d94a7e 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -1158,7 +1158,7 @@ static int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
1158 1158
1159 for (x = 0; x < length; x++) { 1159 for (x = 0; x < length; x++) {
1160 bi = rgd->rd_bits + x; 1160 bi = rgd->rd_bits + x;
1161 error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, &bi->bi_bh); 1161 error = gfs2_meta_read(gl, rgd->rd_addr + x, 0, 0, &bi->bi_bh);
1162 if (error) 1162 if (error)
1163 goto fail; 1163 goto fail;
1164 } 1164 }
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 894fb01a91da..8f94282db2fe 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -1633,6 +1633,7 @@ static struct inode *gfs2_alloc_inode(struct super_block *sb)
1633 ip->i_gl = NULL; 1633 ip->i_gl = NULL;
1634 ip->i_rgd = NULL; 1634 ip->i_rgd = NULL;
1635 ip->i_res = NULL; 1635 ip->i_res = NULL;
1636 ip->i_rahead = 0;
1636 } 1637 }
1637 return &ip->i_inode; 1638 return &ip->i_inode;
1638} 1639}
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index 4c096fa9e2a1..f0fe88449bd2 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -119,7 +119,7 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
119 __be64 *eablk, *end; 119 __be64 *eablk, *end;
120 int error; 120 int error;
121 121
122 error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &bh); 122 error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, 0, &bh);
123 if (error) 123 if (error)
124 return error; 124 return error;
125 125
@@ -143,7 +143,7 @@ static int ea_foreach(struct gfs2_inode *ip, ea_call_t ea_call, void *data)
143 break; 143 break;
144 bn = be64_to_cpu(*eablk); 144 bn = be64_to_cpu(*eablk);
145 145
146 error = gfs2_meta_read(ip->i_gl, bn, DIO_WAIT, &eabh); 146 error = gfs2_meta_read(ip->i_gl, bn, DIO_WAIT, 0, &eabh);
147 if (error) 147 if (error)
148 break; 148 break;
149 error = ea_foreach_i(ip, eabh, ea_call, data); 149 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 return -ENOMEM; 477 return -ENOMEM;
478 478
479 for (x = 0; x < nptrs; x++) { 479 for (x = 0; x < nptrs; x++) {
480 error = gfs2_meta_read(ip->i_gl, be64_to_cpu(*dataptrs), 0, 480 error = gfs2_meta_read(ip->i_gl, be64_to_cpu(*dataptrs), 0, 0,
481 bh + x); 481 bh + x);
482 if (error) { 482 if (error) {
483 while (x--) 483 while (x--)
@@ -977,7 +977,7 @@ static int ea_set_block(struct gfs2_inode *ip, struct gfs2_ea_request *er,
977 if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) { 977 if (ip->i_diskflags & GFS2_DIF_EA_INDIRECT) {
978 __be64 *end; 978 __be64 *end;
979 979
980 error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, 980 error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, 0,
981 &indbh); 981 &indbh);
982 if (error) 982 if (error)
983 return error; 983 return error;
@@ -1303,7 +1303,7 @@ static int ea_dealloc_indirect(struct gfs2_inode *ip)
1303 1303
1304 memset(&rlist, 0, sizeof(struct gfs2_rgrp_list)); 1304 memset(&rlist, 0, sizeof(struct gfs2_rgrp_list));
1305 1305
1306 error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, &indbh); 1306 error = gfs2_meta_read(ip->i_gl, ip->i_eattr, DIO_WAIT, 0, &indbh);
1307 if (error) 1307 if (error)
1308 return error; 1308 return error;
1309 1309