[Devel] [PATCH rh7] xfs: add missing ub_io_account_dirty in set_page_dirty

Vladimir Davydov vdavydov at virtuozzo.com
Wed Oct 21 02:08:08 PDT 2015


To account dirty pages to beancounter, we call ub_io_account_dirty from
__set_page_dirty_nobuffers and __set_page_dirty, on top of which all
helpers for marking a page as dirty are built. There is one exception
though - xfs_vm_set_page_dirty does not use any of these. It would use
__set_page_dirty if it was not static, but since it is, it simply copies
it. That said, we need to call ub_io_account_dirty from this function
either, otherwise a warning will be issued:

  WARNING: at kernel/bc/io_acct.c:80 ub_io_account_cancel+0x11a/0x130()
  Call Trace:
   [<ffffffff815fd64f>] dump_stack+0x19/0x1b
   [<ffffffff8106e59b>] warn_slowpath_common+0x6b/0xb0
   [<ffffffff8106e6ea>] warn_slowpath_null+0x1a/0x20
   [<ffffffff810de49a>] ub_io_account_cancel+0x11a/0x130
   [<ffffffff81168f78>] __delete_from_page_cache+0x2f8/0x350
   [<ffffffff8116900e>] delete_from_page_cache+0x3e/0xa0
   [<ffffffff8117772b>] truncate_inode_page+0x5b/0x80
   [<ffffffff81177986>] truncate_inode_pages_range+0x1f6/0x740
   [<ffffffff811c028b>] ? kmem_cache_free+0xab/0x1e0
   [<ffffffffa0115ffe>] ? xfs_trans_free+0x6e/0x80 [xfs]
   [<ffffffffa0117276>] ? xfs_trans_commit+0x146/0x240 [xfs]
   [<ffffffffa01494a6>] ? xfs_inode_is_filestream+0x46/0x70 [xfs]
   [<ffffffffa014c94a>] ? xfs_remove+0x36a/0x380 [xfs]
   [<ffffffff81209420>] ? __inode_wait_for_writeback+0x80/0xf0
   [<ffffffff81177f4e>] truncate_inode_pages_final+0x5e/0x90
   [<ffffffffa01130b9>] xfs_fs_evict_inode+0x29/0xc0 [xfs]
   [<ffffffff811faf47>] evict+0xa7/0x170
   [<ffffffff811fb82b>] iput+0x18b/0x1f0
   [<ffffffff811efbbe>] do_unlinkat+0x1ae/0x2b0
   [<ffffffff81608dda>] ? do_page_fault+0x1a/0x70
   [<ffffffff811f0cd6>] SyS_unlink+0x16/0x20
   [<ffffffff8160d589>] system_call_fastpath+0x16/0x1b

Since we do not officially support XFS, it is not critical for us,
nevertheless let us fix it in case anybody tries to use it.

Reported-by: Alexey Lyashkov <umka at cloudlinux.com>
Signed-off-by: Vladimir Davydov <vdavydov at virtuozzo.com>
---
 fs/xfs/xfs_aops.c   | 6 ++++++
 kernel/bc/io_acct.c | 1 +
 2 files changed, 7 insertions(+)

diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index a02548f98f3a..7a7f59c7e507 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -39,6 +39,7 @@
 #include <linux/mpage.h>
 #include <linux/pagevec.h>
 #include <linux/writeback.h>
+#include <bc/io_acct.h>
 
 void
 xfs_count_page_state(
@@ -1796,6 +1797,11 @@ xfs_vm_set_page_dirty(
 			account_page_dirtied(page, mapping);
 			radix_tree_tag_set(&mapping->page_tree,
 					page_index(page), PAGECACHE_TAG_DIRTY);
+			if (mapping_cap_account_dirty(mapping) &&
+					!radix_tree_prev_tag_get(
+						&mapping->page_tree,
+						PAGECACHE_TAG_DIRTY))
+				ub_io_account_dirty(mapping);
 		}
 		spin_unlock_irqrestore(&mapping->tree_lock, flags);
 		__mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
diff --git a/kernel/bc/io_acct.c b/kernel/bc/io_acct.c
index 109004fa18a4..f9778f8eb5bf 100644
--- a/kernel/bc/io_acct.c
+++ b/kernel/bc/io_acct.c
@@ -45,6 +45,7 @@ void ub_io_account_dirty(struct address_space *mapping)
 
 	ub_stat_inc(ub, dirty_pages);
 }
+EXPORT_SYMBOL_GPL(ub_io_account_dirty);
 
 void ub_io_account_clean(struct address_space *mapping)
 {
-- 
2.1.4




More information about the Devel mailing list