Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Nanzhe Zhao and committed by
Jaegeuk Kim
c0c589fa 00feea1d

+12 -9
+12 -9
fs/f2fs/data.c
··· 2497 2497 continue; 2498 2498 } 2499 2499 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 + 2500 2512 /* 2501 2513 * This page will go to BIO. Do we need to send this 2502 2514 * BIO off first? ··· 2535 2523 if (!bio_add_folio(bio, folio, F2FS_BLKSIZE, 2536 2524 offset << PAGE_SHIFT)) 2537 2525 goto submit_and_realloc; 2538 - 2539 - if (folio_test_large(folio)) { 2540 - ffs = ffs_find_or_alloc(folio); 2541 - 2542 - /* set the bitmap to wait */ 2543 - spin_lock_irq(&ffs->state_lock); 2544 - ffs->read_pages_pending++; 2545 - spin_unlock_irq(&ffs->state_lock); 2546 - } 2547 2526 2548 2527 inc_page_count(F2FS_I_SB(inode), F2FS_RD_DATA); 2549 2528 f2fs_update_iostat(F2FS_I_SB(inode), NULL, FS_DATA_READ_IO,