Re: [PATCH] gfs2: fix hung task in gfs2_jhead_process_page

From: Andreas Gruenbacher

Date: Tue Mar 24 2026 - 21:43:39 EST


On Wed, Mar 25, 2026 at 1:07 AM Deepanshu Kartikey
<kartikey406@xxxxxxxxx> wrote:
> On Tue, Mar 24, 2026 at 8:16 PM Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote:
> >
> > I have my doubts that this is the right fix. If you look at the entire
> > function, it assumes that the folio was already created and added to
> > the page cache. The error should surely be detected earlier, not by
> > this function.
> >
>
> Hi Mathew,
>
> Thank you for the review. After further analysis, we found that the
> bug is triggered by a malicious/corrupted GFS2 filesystem image
> whose journal extent list contains extents with gaps between them:
>
> extent 1: lblock=0, dblock=1000, blocks=2
> extent 2: lblock=100, dblock=2000, blocks=2

How about something like this?

--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -2210,7 +2210,7 @@ void gfs2_free_journal_extents(struct gfs2_jdesc *jd)
* @dblock: The physical block at start of new extent
* @blocks: Size of extent in fs blocks
*
- * Returns: 0 on success or -ENOMEM
+ * Returns: 0 on success, or an error code
*/

static int gfs2_add_jextent(struct gfs2_jdesc *jd, u64 lblock, u64
dblock, u64 blocks)
@@ -2219,6 +2219,8 @@ static int gfs2_add_jextent(struct gfs2_jdesc
*jd, u64 lblock, u64 dblock, u64 b

if (!list_empty(&jd->extent_list)) {
jext = list_last_entry(&jd->extent_list, struct
gfs2_journal_extent, list);
+ if (jext->lblock + jext->blocks != lblock)
+ return -EINVAL;
if ((jext->dblock + jext->blocks) == dblock) {
jext->blocks += blocks;
return 0;

Thanks,
Andreas