f2fs_read_data_large_folio() can build a single read BIO across multiple folios during readahead. If a folio ends up having none of its subpages added to the BIO (e.g. all subpages are zeroed / treated as holes), it will never be seen by f2fs_finish_read_bio(), so folio_end_read() is never called. This leaves the folio locked and not marked uptodate.
Track whether the current folio has been added to a BIO via a local 'folio_in_bio' bool flag, and when iterating readahead folios, explicitly mark the folio uptodate (on success) and unlock it when nothing was added. Signed-off-by: Nanzhe Zhao <[email protected]> --- fs/f2fs/data.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index f32eb51ccee4..ddabcb1b9882 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -2436,6 +2436,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; if (!IS_IMMUTABLE(inode)) return -EOPNOTSUPP; @@ -2451,6 +2452,7 @@ static int f2fs_read_data_large_folio(struct inode *inode, if (!folio) goto out; + folio_in_bio = false; index = folio->index; offset = 0; ffs = NULL; @@ -2536,6 +2538,7 @@ static int f2fs_read_data_large_folio(struct inode *inode, offset << PAGE_SHIFT)) goto submit_and_realloc; + folio_in_bio = true; inc_page_count(F2FS_I_SB(inode), F2FS_RD_DATA); f2fs_update_iostat(F2FS_I_SB(inode), NULL, FS_DATA_READ_IO, F2FS_BLKSIZE); @@ -2545,6 +2548,11 @@ static int f2fs_read_data_large_folio(struct inode *inode, } trace_f2fs_read_folio(folio, DATA); if (rac) { + if (!folio_in_bio) { + if (!ret) + folio_mark_uptodate(folio); + folio_unlock(folio); + } folio = readahead_folio(rac); goto next_folio; } -- 2.34.1 _______________________________________________ Linux-f2fs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
