Add clear_dirty_for_io_stats() which clears dirty stats corresponding to a folio. The main use case for this is for filesystems that implement granular dirty writeback for large folios. This allows them (after setting the wbc no_stats_accounting bitfield) to update dirty writeback stats only for the pages in the folio that are written back instead of for the entire folio, which helps enforce more accurate / less conservative dirty page balancing. Signed-off-by: Joanne Koong --- include/linux/writeback.h | 1 + mm/page-writeback.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/linux/writeback.h b/include/linux/writeback.h index f63a52b56dff..2ae0bea03d48 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -375,6 +375,7 @@ int write_cache_pages(struct address_space *mapping, void *data); int do_writepages(struct address_space *mapping, struct writeback_control *wbc); void writeback_set_ratelimit(void); +void clear_dirty_for_io_stats(struct folio *folio, long nr_pages); void tag_pages_for_writeback(struct address_space *mapping, pgoff_t start, pgoff_t end); diff --git a/mm/page-writeback.c b/mm/page-writeback.c index e0410cfbe480..726da7611cce 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -2709,6 +2709,22 @@ static void __clear_dirty_for_io_stats(struct folio *folio, wb_stat_mod(wb, WB_RECLAIMABLE, -nr_pages); } +void clear_dirty_for_io_stats(struct folio *folio, long nr_pages) +{ + struct address_space *mapping = folio_mapping(folio); + struct bdi_writeback *wb; + struct wb_lock_cookie cookie = {}; + struct inode *inode; + + if (!mapping || !mapping_can_writeback(mapping)) + return; + + inode = mapping->host; + wb = unlocked_inode_to_wb_begin(inode, &cookie); + __clear_dirty_for_io_stats(folio, wb, nr_pages); + unlocked_inode_to_wb_end(inode, &cookie); +} + /* * Helper function for deaccounting dirty page without writeback. * -- 2.47.3