[PATCH Next] gfs2: update end and prev bio for chain bio

Edward Adam Davis <[email protected]>
Newsgroups dev.linux.lists.gfs2,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The bios are created and initialized using gfs2_log_alloc_bio() in
gfs2_find_jhead(), which sets bi_end_io and bi_private. When the I/O
request is too large and needs to be split into multiple bios and
submitted as a chain, the bug reported by syzbot [1] is triggered.

When we need to submit multiple bios in a chain, we need to pass the
bi_end_io and bi_private of the previous bio to the end bio to ensure
that the multiple bios are correctly assembled into a submission chain.

[1]
kernel BUG at block/bio.c:342!
Call Trace:
 gfs2_chain_bio fs/gfs2/lops.c:487 [inline]
 gfs2_find_jhead+0x627/0xe40 fs/gfs2/lops.c:549
 gfs2_recover_func+0x5f5/0x1c90 fs/gfs2/recovery.c:459

Fixes: 8a157e0a0aa5 ("gfs2: Fix use of bio_chain")
Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=f6539d4ce3f775aee0cc
Signed-off-by: Edward Adam Davis <[email protected]>
---
 fs/gfs2/lops.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 97ebe457c00a..2de334034c74 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -484,6 +484,10 @@ static struct bio *gfs2_chain_bio(struct bio *prev, unsigned int nr_iovecs)
 	new = bio_alloc(prev->bi_bdev, nr_iovecs, prev->bi_opf, GFP_NOIO);
 	bio_clone_blkg_association(new, prev);
 	new->bi_iter.bi_sector = bio_end_sector(prev);
+	new->bi_end_io = prev->bi_end_io;
+	new->bi_private = prev->bi_private;
+	prev->bi_end_io = NULL;
+	prev->bi_private = NULL;
 	bio_chain(prev, new);
 	submit_bio(prev);
 	return new;
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.