Skip to content

Commit c0c589f

Browse files
sigmanatureJaegeuk Kim
authored andcommitted
f2fs: Accounting large folio subpages before bio submission
In f2fs_read_data_large_folio(), read_pages_pending is incremented only after the subpage has been added to the BIO. With a heavily fragmented file, each new subpage can force submission of the previous BIO. If the BIO completes quickly, f2fs_finish_read_bio() may decrement read_pages_pending to zero and call folio_end_read() while the read loop is still processing other subpages of the same large folio. Fix the ordering by incrementing read_pages_pending before any possible BIO submission for the current subpage, matching the iomap ordering and preventing premature folio_end_read(). Signed-off-by: Nanzhe Zhao <nzzhao@126.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent 00feea1 commit c0c589f

1 file changed

Lines changed: 12 additions & 9 deletions

File tree

fs/f2fs/data.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2497,6 +2497,18 @@ static int f2fs_read_data_large_folio(struct inode *inode,
24972497
continue;
24982498
}
24992499

2500+
/* We must increment read_pages_pending before possible BIOs submitting
2501+
* to prevent from premature folio_end_read() call on folio
2502+
*/
2503+
if (folio_test_large(folio)) {
2504+
ffs = ffs_find_or_alloc(folio);
2505+
2506+
/* set the bitmap to wait */
2507+
spin_lock_irq(&ffs->state_lock);
2508+
ffs->read_pages_pending++;
2509+
spin_unlock_irq(&ffs->state_lock);
2510+
}
2511+
25002512
/*
25012513
* This page will go to BIO. Do we need to send this
25022514
* BIO off first?
@@ -2524,15 +2536,6 @@ static int f2fs_read_data_large_folio(struct inode *inode,
25242536
offset << PAGE_SHIFT))
25252537
goto submit_and_realloc;
25262538

2527-
if (folio_test_large(folio)) {
2528-
ffs = ffs_find_or_alloc(folio);
2529-
2530-
/* set the bitmap to wait */
2531-
spin_lock_irq(&ffs->state_lock);
2532-
ffs->read_pages_pending++;
2533-
spin_unlock_irq(&ffs->state_lock);
2534-
}
2535-
25362539
inc_page_count(F2FS_I_SB(inode), F2FS_RD_DATA);
25372540
f2fs_update_iostat(F2FS_I_SB(inode), NULL, FS_DATA_READ_IO,
25382541
F2FS_BLKSIZE);

0 commit comments

Comments
 (0)