[PATCH] gfs2: keep per-bio end_io when splitting journal head reads

Wxm-233 <[email protected]> Fri, 24 Apr 2026 12:06:56 +0800
Newsgroups dev.linux.lists.gfs2,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
gfs2_find_jhead() can split a folio across two bios when part of the
folio is already queued in the current bio and the remaining blocks
need a new bio.

That split path currently calls bio_chain(new, prev).  But journal read
bios need to retain gfs2_end_log_read() and bi_private so that each bio
completes its own folios with folio_end_read().  Replacing the new
bio's completion handler with the block layer chaining callback breaks
that expectation, and fuzzing workloads can hit a BUG in bio_chain()
on this path.

Keep the per-bio completion state for the new bio and only submit the
previous bio.

Signed-off-by: Wxm-233 <[email protected]>
---
 fs/gfs2/lops.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 6586963..3d0fad3 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -481,12 +481,16 @@ static void gfs2_jhead_process_page(struct gfs2_jdesc *jd, unsigned long index,
 static struct bio *gfs2_chain_bio(struct bio *prev, unsigned int nr_iovecs,
 				  sector_t sector, blk_opf_t opf)
 {
+	bio_end_io_t *end_io = prev->bi_end_io;
+	void *private = prev->bi_private;
 	struct bio *new;
 
 	new = bio_alloc(prev->bi_bdev, nr_iovecs, opf, GFP_NOIO);
 	bio_clone_blkg_association(new, prev);
 	new->bi_iter.bi_sector = sector;
-	bio_chain(new, prev);
+	/* Each journal read bio must complete its own folios. */
+	new->bi_end_io = end_io;
+	new->bi_private = private;
 	submit_bio(prev);
 	return new;
 }
-- 
2.45.2.windows.1