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

Andreas Gruenbacher <[email protected]> Wed, 25 Mar 2026 02:42:44 +0100
Newsgroups dev.linux.lists.gfs2,org.kernel.vger.linux-kernel
Message-ID <CAHc6FU5YouqqiyPgPsNshw50NCEiptzf=yePwEujGKu8NtHA7Q@mail.gmail.com>
On Wed, Mar 25, 2026 at 1:07 AM Deepanshu Kartikey
<[email protected]> wrote:
> On Tue, Mar 24, 2026 at 8:16 PM Matthew Wilcox <[email protected]> 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