|
|
@@ -530,8 +530,6 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
|
|
|
|
|
|
isw->inode = inode;
|
|
|
|
|
|
- atomic_inc(&isw_nr_in_flight);
|
|
|
-
|
|
|
/*
|
|
|
* In addition to synchronizing among switchers, I_WB_SWITCH tells
|
|
|
* the RCU protected stat update paths to grab the i_page
|
|
|
@@ -539,6 +537,9 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
|
|
|
* Let's continue after I_WB_SWITCH is guaranteed to be visible.
|
|
|
*/
|
|
|
call_rcu(&isw->rcu_head, inode_switch_wbs_rcu_fn);
|
|
|
+
|
|
|
+ atomic_inc(&isw_nr_in_flight);
|
|
|
+
|
|
|
goto out_unlock;
|
|
|
|
|
|
out_free:
|
|
|
@@ -908,7 +909,11 @@ restart:
|
|
|
void cgroup_writeback_umount(void)
|
|
|
{
|
|
|
if (atomic_read(&isw_nr_in_flight)) {
|
|
|
- synchronize_rcu();
|
|
|
+ /*
|
|
|
+ * Use rcu_barrier() to wait for all pending callbacks to
|
|
|
+ * ensure that all in-flight wb switches are in the workqueue.
|
|
|
+ */
|
|
|
+ rcu_barrier();
|
|
|
flush_workqueue(isw_wq);
|
|
|
}
|
|
|
}
|