[PATCH 5/5] gfs2: check for errors from filemap_get_folio() in gfs2_jhead_process_page()

From: Mauricio Faria de Oliveira

Date: Tue Sep 08 2026 - 17:21:59 EST


Let's check for a not-found folio pointer error, that is, ERR_PTR(-ENOENT),
just in case, even though it is not expected (due to a previously acquired
reference on the folio, per the function comment).

If filemap_get_folio() returns an error, log it and return -EIO. The only
caller is gfs2_chain_bio() (same file), twice, which can currently return
errors, thus propagate the error.

Signed-off-by: Mauricio Faria de Oliveira <mfo@xxxxxxxxxx>
---
fs/gfs2/lops.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 192e71e630dce062361cc754f2ba878fa23c0a7f..78cadde990182223978ddbde2be25cfe963beabe 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -459,14 +459,21 @@ static bool gfs2_jhead_folio_search(struct gfs2_jdesc *jd,
* our references to the folio.
*/

-static void gfs2_jhead_process_page(struct gfs2_jdesc *jd, unsigned long index,
- struct gfs2_log_header_host *head,
- bool *done)
+static int gfs2_jhead_process_page(struct gfs2_jdesc *jd, unsigned long index,
+ struct gfs2_log_header_host *head,
+ bool *done)
{
+ struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
struct folio *folio;

folio = filemap_get_folio(jd->jd_inode->i_mapping, index);

+ /* This should not happen (see comment above), but check just in case */
+ if (IS_ERR(folio)) {
+ fs_err(sdp, "Error %ld getting folio.\n", PTR_ERR(folio));
+ return -EIO;
+ }
+
folio_wait_locked(folio);
if (!folio_test_uptodate(folio))
*done = true;
@@ -476,6 +483,7 @@ static void gfs2_jhead_process_page(struct gfs2_jdesc *jd, unsigned long index,

/* filemap_get_folio() and the earlier filemap_grab_folio() */
folio_put_refs(folio, 2);
+ return 0;
}

static struct bio *gfs2_chain_bio(struct bio *prev, unsigned int nr_iovecs,
@@ -572,7 +580,9 @@ int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head)
continue;
}

- gfs2_jhead_process_page(jd, blocks_read >> shift, head, &done);
+ ret = gfs2_jhead_process_page(jd, blocks_read >> shift, head, &done);
+ if (ret)
+ goto error;
blocks_read += PAGE_SIZE >> bsize_shift;
if (done)
goto out; /* found */
@@ -583,7 +593,9 @@ int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head)
if (bio)
submit_bio(bio);
while (blocks_read < block) {
- gfs2_jhead_process_page(jd, blocks_read >> shift, head, &done);
+ ret = gfs2_jhead_process_page(jd, blocks_read >> shift, head, &done);
+ if (ret)
+ goto error;
blocks_read += PAGE_SIZE >> bsize_shift;
}

@@ -592,6 +604,7 @@ int gfs2_find_jhead(struct gfs2_jdesc *jd, struct gfs2_log_header_host *head)

truncate_inode_pages(mapping, 0);

+error:
return ret;
}


--
2.47.3