Skip to content

Commit aa83da7

Browse files
author
Andreas Gruenbacher
committed
gfs2: More gfs2_find_jhead fixes
It turns out that when extending an existing bio, gfs2_find_jhead fails to check if the block number is consecutive, which leads to incorrect reads for fragmented journals. In addition, limit the maximum bio size to an arbitrary value of 2 megabytes: since commit 07173c3 ("block: enable multipage bvecs"), if we just keep adding pages until bio_add_page fails, bios will grow much larger than useful, which pins more memory than necessary with barely any additional performance gains. Fixes: f4686c2 ("gfs2: read journal in large chunks") Cc: [email protected] # v5.2+ Signed-off-by: Andreas Gruenbacher <[email protected]> Signed-off-by: Bob Peterson <[email protected]>
1 parent 566a2ab commit aa83da7

File tree

1 file changed

+12
-7
lines changed

1 file changed

+12
-7
lines changed

fs/gfs2/lops.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ static struct bio *gfs2_log_alloc_bio(struct gfs2_sbd *sdp, u64 blkno,
263263
struct super_block *sb = sdp->sd_vfs;
264264
struct bio *bio = bio_alloc(GFP_NOIO, BIO_MAX_PAGES);
265265

266-
bio->bi_iter.bi_sector = blkno << (sb->s_blocksize_bits - 9);
266+
bio->bi_iter.bi_sector = blkno << sdp->sd_fsb2bb_shift;
267267
bio_set_dev(bio, sb->s_bdev);
268268
bio->bi_end_io = end_io;
269269
bio->bi_private = sdp;
@@ -509,7 +509,7 @@ int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head,
509509
unsigned int bsize = sdp->sd_sb.sb_bsize, off;
510510
unsigned int bsize_shift = sdp->sd_sb.sb_bsize_shift;
511511
unsigned int shift = PAGE_SHIFT - bsize_shift;
512-
unsigned int readahead_blocks = BIO_MAX_PAGES << shift;
512+
unsigned int max_bio_size = 2 * 1024 * 1024;
513513
struct gfs2_journal_extent *je;
514514
int sz, ret = 0;
515515
struct bio *bio = NULL;
@@ -537,12 +537,17 @@ int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head,
537537
off = 0;
538538
}
539539

540-
if (!bio || (bio_chained && !off)) {
540+
if (!bio || (bio_chained && !off) ||
541+
bio->bi_iter.bi_size >= max_bio_size) {
541542
/* start new bio */
542543
} else {
543-
sz = bio_add_page(bio, page, bsize, off);
544-
if (sz == bsize)
545-
goto block_added;
544+
sector_t sector = dblock << sdp->sd_fsb2bb_shift;
545+
546+
if (bio_end_sector(bio) == sector) {
547+
sz = bio_add_page(bio, page, bsize, off);
548+
if (sz == bsize)
549+
goto block_added;
550+
}
546551
if (off) {
547552
unsigned int blocks =
548553
(PAGE_SIZE - off) >> bsize_shift;
@@ -568,7 +573,7 @@ int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head,
568573
off += bsize;
569574
if (off == PAGE_SIZE)
570575
page = NULL;
571-
if (blocks_submitted < blocks_read + readahead_blocks) {
576+
if (blocks_submitted < 2 * max_bio_size >> bsize_shift) {
572577
/* Keep at least one bio in flight */
573578
continue;
574579
}

0 commit comments

Comments
 (0)