[Devel] [PATCH rh7] fs: access dirtied_ub under rcu lock in __writeback_single_inode

Vladimir Davydov vdavydov at parallels.com
Mon Jun 15 07:18:36 PDT 2015


Unlike RH6, we are not holding any locks in __writeback_single_inode, so
we must dereference dirtied_ub carefully, under rcu read lock.

Also, if dirtied_ub == NULL, account writeback to ub0 as suggested by
dmonakhov at .

Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
 fs/fs-writeback.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 8362cc933e68..b2f77f4ed0a0 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -491,16 +491,18 @@ __do_writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 static int
 __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 {
-	struct user_beancounter *ub = inode->i_mapping->dirtied_ub;
+	struct user_beancounter *ub;
 	int ret;
 
-	if (likely(get_exec_ub() == ub || !ub))
-		return __do_writeback_single_inode(inode, wbc);
+	rcu_read_lock();
+	ub = rcu_dereference(inode->i_mapping->dirtied_ub);
+	if (!ub || !get_beancounter_rcu(ub))
+		ub = get_beancounter(get_ub0());
+	rcu_read_unlock();
 
-	ub = get_beancounter_rcu(ub) ? set_exec_ub(ub) : NULL;
+	ub = set_exec_ub(ub);
 	ret = __do_writeback_single_inode(inode, wbc);
-	if (ub)
-		put_beancounter(set_exec_ub(ub));
+	put_beancounter(set_exec_ub(ub));
 
 	return ret;
 }
-- 
2.1.4




More information about the Devel mailing list