diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2015-11-11 16:00:35 -0500 |
---|---|---|
committer | Bob Peterson <rpeterso@redhat.com> | 2015-11-16 13:00:29 -0500 |
commit | c8d577038449a718ad0027d1790b6ef4441715d4 (patch) | |
tree | 7ba2dd87040f008328b528e96ac99b88736188f7 | |
parent | 3dd1dd8c696bdb7c8dcc9456cb23558ad1b336b8 (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.c | 15 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 1 | ||||
-rw-r--r-- | fs/gfs2/meta_io.c | 27 | ||||
-rw-r--r-- | fs/gfs2/meta_io.h | 2 | ||||
-rw-r--r-- | fs/gfs2/quota.c | 2 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 2 | ||||
-rw-r--r-- | fs/gfs2/super.c | 1 | ||||
-rw-r--r-- | fs/gfs2/xattr.c | 10 |
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 | ||
190 | static 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 | ||
200 | int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, | 215 | int 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 | ||
54 | extern struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno); | 54 | extern struct buffer_head *gfs2_meta_new(struct gfs2_glock *gl, u64 blkno); |
55 | extern int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, | 55 | extern int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags, |
56 | struct buffer_head **bhp); | 56 | int rahead, struct buffer_head **bhp); |
57 | extern int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh); | 57 | extern int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh); |
58 | extern struct buffer_head *gfs2_getbuf(struct gfs2_glock *gl, u64 blkno, | 58 | extern 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 | ||