summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWenjie Qi <qiwenjie@xiaomi.com>2026-05-20 12:52:04 +0300
committerJaegeuk Kim <jaegeuk@kernel.org>2026-06-22 22:52:35 +0300
commit74c8d2ec95c59a5651ecd975c466998af1961fd4 (patch)
treec92c4b1cef3cbabbbbe253ba26adb9f6ee459ef0
parente0288584baa5dc41df4a829a023c4c1b33fe53d7 (diff)
downloadlinux-74c8d2ec95c59a5651ecd975c466998af1961fd4.tar.xz
f2fs: fix missing read bio submission on large folio error
f2fs_read_data_large_folio() can keep a read bio across multiple readahead folios. If a later folio hits an error before any of its blocks are added to the bio, folio_in_bio is false and the current error path returns immediately after ending that folio. This can leave the bio accumulated for earlier folios unsubmitted. Those folios then never receive read completion, and readers can wait indefinitely on the locked folios. Route errors through the common out path so any pending bio is submitted before returning. Stop consuming more readahead folios once an error is seen, and only wait on and clear the current folio when it was actually added to the bio. Cc: stable@kernel.org Fixes: a5d8b9d94e18 ("f2fs: fix to unlock folio in f2fs_read_data_large_folio()") Signed-off-by: Wenjie Qi <qiwenjie@xiaomi.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fs/f2fs/data.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 5d18119a214a..d83a21998ec2 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2529,7 +2529,7 @@ static int f2fs_read_data_large_folio(struct inode *inode,
unsigned nrpages;
struct f2fs_folio_state *ffs;
int ret = 0;
- bool folio_in_bio;
+ bool folio_in_bio = false;
if (!IS_IMMUTABLE(inode) || f2fs_compressed_file(inode)) {
if (folio)
@@ -2645,18 +2645,17 @@ submit_and_realloc:
}
trace_f2fs_read_folio(folio, DATA);
err_out:
- if (!folio_in_bio) {
+ if (!folio_in_bio)
folio_end_read(folio, !ret);
- if (ret)
- return ret;
- }
+ if (ret)
+ goto out;
if (rac) {
folio = readahead_folio(rac);
goto next_folio;
}
out:
f2fs_submit_read_bio(F2FS_I_SB(inode), bio, DATA);
- if (ret) {
+ if (ret && folio_in_bio) {
/* Wait bios and clear uptodate. */
folio_lock(folio);
folio_clear_uptodate(folio);