struct inode_switch_wbs_context *isw, *next_isw;
struct llist_node *list;
+ list = llist_del_all(&new_wb->switch_wbs_ctxs);
/*
- * Grab out reference to wb so that it cannot get freed under us
+ * Nothing to do? That would be a problem as references held by isw
+ * items protect wb from freeing...
+ */
+ if (WARN_ON_ONCE(!list))
+ return;
+
+ /*
+ * Grab our reference to wb so that it cannot get freed under us
* after we process all the isw items.
*/
wb_get(new_wb);
- while (1) {
- list = llist_del_all(&new_wb->switch_wbs_ctxs);
- /* Nothing to do? */
- if (!list)
- break;
- /*
- * In addition to synchronizing among switchers, I_WB_SWITCH
- * tells the RCU protected stat update paths to grab the i_page
- * lock so that stat transfer can synchronize against them.
- * Let's continue after I_WB_SWITCH is guaranteed to be
- * visible.
- */
- synchronize_rcu();
+ /*
+ * In addition to synchronizing among switchers, I_WB_SWITCH
+ * tells the RCU protected stat update paths to grab the i_page
+ * lock so that stat transfer can synchronize against them.
+ * Let's continue after I_WB_SWITCH is guaranteed to be
+ * visible.
+ */
+ synchronize_rcu();
- llist_for_each_entry_safe(isw, next_isw, list, list)
- process_inode_switch_wbs(new_wb, isw);
- }
+ llist_for_each_entry_safe(isw, next_isw, list, list)
+ process_inode_switch_wbs(new_wb, isw);
wb_put(new_wb);
}