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

Andreas Gruenbacher <[email protected]> Fri, 24 Apr 2026 14:44:14 +0200
Newsgroups dev.linux.lists.gfs2,org.kernel.vger.linux-kernel
Message-ID <CAHc6FU5C-qu_mtN8FnXy3nY_jnskDr2EQqESqCrwU4MrDy9_VQ@mail.gmail.com>
Hello,

On Fri, Apr 24, 2026 at 6:16 AM Wxm-233 <[email protected]> wrote:
> 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,

please see commit 469d71512d13 ('Revert "gfs2: Fix use of bio_chain"')
for a hint on how this works.

> and fuzzing workloads can hit a BUG in bio_chain() on this path.

What specific test case / reproducer is causing problems?

> 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;

We surely are not going to hand-roll bio_chain().

>         submit_bio(prev);
>         return new;
>  }
> --
> 2.45.2.windows.1
>

Thanks,
Andreas