aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruenba@redhat.com>2016-08-16 07:25:22 -0400
committerBob Peterson <rpeterso@redhat.com>2016-08-18 12:36:41 -0400
commit23e5671a79be00b2f1c895aa93ff40fb75a4647e (patch)
tree46772f1b850c86f7b7a3914137e6c78548dbc9b3
parent1c185c02f454c47d573a17e3e7d8befb06f0d64d (diff)
gfs2: Fix extended attribute readahead optimization
Commit 39b0555f didn't check for a failing bio_add_page in gfs2_submit_bhs. This could cause I/O requests to get lost, and the affected buffer heads to stay locked forever. Fix that by submitting the current bio and allocating another one when bio_add_page fails. (It is guaranteed that we can at least add one page to a bio.) Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Bob Peterson <rpeterso@redhat.com>
-rw-r--r--fs/gfs2/meta_io.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index 950b8be68e41..373639a59782 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -216,23 +216,26 @@ static void gfs2_meta_read_endio(struct bio *bio)
216static void gfs2_submit_bhs(int op, int op_flags, struct buffer_head *bhs[], 216static void gfs2_submit_bhs(int op, int op_flags, struct buffer_head *bhs[],
217 int num) 217 int num)
218{ 218{
219 struct buffer_head *bh = bhs[0]; 219 while (num > 0) {
220 struct bio *bio; 220 struct buffer_head *bh = *bhs;
221 int i; 221 struct bio *bio;
222 222
223 if (!num) 223 bio = bio_alloc(GFP_NOIO, num);
224 return; 224 bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9);
225 225 bio->bi_bdev = bh->b_bdev;
226 bio = bio_alloc(GFP_NOIO, num); 226 while (num > 0) {
227 bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9); 227 bh = *bhs;
228 bio->bi_bdev = bh->b_bdev; 228 if (!bio_add_page(bio, bh->b_page, bh->b_size, bh_offset(bh))) {
229 for (i = 0; i < num; i++) { 229 BUG_ON(bio->bi_iter.bi_size == 0);
230 bh = bhs[i]; 230 break;
231 bio_add_page(bio, bh->b_page, bh->b_size, bh_offset(bh)); 231 }
232 bhs++;
233 num--;
234 }
235 bio->bi_end_io = gfs2_meta_read_endio;
236 bio_set_op_attrs(bio, op, op_flags);
237 submit_bio(bio);
232 } 238 }
233 bio->bi_end_io = gfs2_meta_read_endio;
234 bio_set_op_attrs(bio, op, op_flags);
235 submit_bio(bio);
236} 239}
237 240
238/** 241/**