Add an additional arg to __folio_mark_dirty() that takes in the number of pages dirtied, so that this can be passed to folio_account_dirtied() when it updates the stats. Signed-off-by: Joanne Koong --- fs/buffer.c | 6 ++++-- include/linux/pagemap.h | 3 ++- mm/page-writeback.c | 10 +++++----- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index 6a8752f7bbed..65c96c432800 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -751,7 +751,8 @@ bool block_dirty_folio(struct address_space *mapping, struct folio *folio) spin_unlock(&mapping->i_private_lock); if (newly_dirty) - __folio_mark_dirty(folio, mapping, 1); + __folio_mark_dirty(folio, mapping, 1, + folio_nr_pages(folio)); if (newly_dirty) __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); @@ -1203,7 +1204,8 @@ void mark_buffer_dirty(struct buffer_head *bh) if (!folio_test_set_dirty(folio)) { mapping = folio->mapping; if (mapping) - __folio_mark_dirty(folio, mapping, 0); + __folio_mark_dirty(folio, mapping, 0, + folio_nr_pages(folio)); } if (mapping) __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 362900730247..48745f8f6dfe 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -1223,7 +1223,8 @@ void end_page_writeback(struct page *page); void folio_end_writeback(struct folio *folio); void folio_end_writeback_pages(struct folio *folio, long nr_pages); void folio_wait_stable(struct folio *folio); -void __folio_mark_dirty(struct folio *folio, struct address_space *, int warn); +void __folio_mark_dirty(struct folio *folio, struct address_space *, int warn, + long nr_pages); void folio_account_cleaned(struct folio *folio, struct bdi_writeback *wb); void __folio_cancel_dirty(struct folio *folio); static inline void folio_cancel_dirty(struct folio *folio) diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 65002552458a..e66eef2d1584 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -2675,7 +2675,7 @@ EXPORT_SYMBOL(noop_dirty_folio); * NOTE: This relies on being atomic wrt interrupts. */ static void folio_account_dirtied(struct folio *folio, - struct address_space *mapping) + struct address_space *mapping, long nr) { struct inode *inode = mapping->host; @@ -2683,7 +2683,6 @@ static void folio_account_dirtied(struct folio *folio, if (mapping_can_writeback(mapping)) { struct bdi_writeback *wb; - long nr = folio_nr_pages(folio); inode_attach_wb(inode, folio); wb = inode_to_wb(inode); @@ -2731,14 +2730,14 @@ void folio_account_cleaned(struct folio *folio, struct bdi_writeback *wb) * try_to_free_buffers() to fail. */ void __folio_mark_dirty(struct folio *folio, struct address_space *mapping, - int warn) + int warn, long nr_pages) { unsigned long flags; xa_lock_irqsave(&mapping->i_pages, flags); if (folio->mapping) { /* Race with truncate? */ WARN_ON_ONCE(warn && !folio_test_uptodate(folio)); - folio_account_dirtied(folio, mapping); + folio_account_dirtied(folio, mapping, nr_pages); __xa_set_mark(&mapping->i_pages, folio_index(folio), PAGECACHE_TAG_DIRTY); } @@ -2769,7 +2768,8 @@ bool filemap_dirty_folio(struct address_space *mapping, struct folio *folio) if (folio_test_set_dirty(folio)) return false; - __folio_mark_dirty(folio, mapping, !folio_test_private(folio)); + __folio_mark_dirty(folio, mapping, !folio_test_private(folio), + folio_nr_pages(folio)); if (mapping->host) { /* !PageAnon && !swapper_space */ -- 2.47.3