[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