diff options
author | Bob Peterson <rpeterso@redhat.com> | 2021-01-21 10:10:26 -0500 |
---|---|---|
committer | Bob Peterson <rpeterso@redhat.com> | 2021-01-25 08:08:44 -0500 |
commit | 82218943058d5e3fe692a38b5a549479738dab33 (patch) | |
tree | b61c5d35b664dc8c89c765cf50192da66b7213e7 /fs/gfs2/lops.c | |
parent | f5f02fde9f52b2d769c1c2ddfd3d9c4a1fe739a7 (diff) | |
download | linux-82218943058d5e3fe692a38b5a549479738dab33.tar.gz linux-82218943058d5e3fe692a38b5a549479738dab33.tar.bz2 linux-82218943058d5e3fe692a38b5a549479738dab33.zip |
gfs2: keep bios separate for each journal
The recovery func can recover multiple journals, but they were all using
the same bio. This resulted in use-after-free related to sdp->sd_log_bio.
This patch moves the variable to the journal descriptor, jd, so that
every recovery can operate on its own bio. And hopefully we never run out.
Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Diffstat (limited to 'fs/gfs2/lops.c')
-rw-r--r-- | fs/gfs2/lops.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index 9e9dd486bed9..921e156d3181 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -322,17 +322,18 @@ static struct bio *gfs2_log_get_bio(struct gfs2_sbd *sdp, u64 blkno, * then add the page segment to that. */ -void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page, - unsigned size, unsigned offset, u64 blkno) +void gfs2_log_write(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd, + struct page *page, unsigned size, unsigned offset, + u64 blkno) { struct bio *bio; int ret; - bio = gfs2_log_get_bio(sdp, blkno, &sdp->sd_log_bio, REQ_OP_WRITE, + bio = gfs2_log_get_bio(sdp, blkno, &jd->jd_log_bio, REQ_OP_WRITE, gfs2_end_log_write, false); ret = bio_add_page(bio, page, size, offset); if (ret == 0) { - bio = gfs2_log_get_bio(sdp, blkno, &sdp->sd_log_bio, + bio = gfs2_log_get_bio(sdp, blkno, &jd->jd_log_bio, REQ_OP_WRITE, gfs2_end_log_write, true); ret = bio_add_page(bio, page, size, offset); WARN_ON(ret == 0); @@ -355,7 +356,8 @@ static void gfs2_log_write_bh(struct gfs2_sbd *sdp, struct buffer_head *bh) dblock = gfs2_log_bmap(sdp->sd_jdesc, sdp->sd_log_flush_head); gfs2_log_incr_head(sdp); - gfs2_log_write(sdp, bh->b_page, bh->b_size, bh_offset(bh), dblock); + gfs2_log_write(sdp, sdp->sd_jdesc, bh->b_page, bh->b_size, + bh_offset(bh), dblock); } /** @@ -376,7 +378,7 @@ static void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page) dblock = gfs2_log_bmap(sdp->sd_jdesc, sdp->sd_log_flush_head); gfs2_log_incr_head(sdp); - gfs2_log_write(sdp, page, sb->s_blocksize, 0, dblock); + gfs2_log_write(sdp, sdp->sd_jdesc, page, sb->s_blocksize, 0, dblock); } /** |