|
@@ -4025,9 +4025,13 @@ static void ocfs2_downconvert_thread_do_work(struct ocfs2_super *osb)
|
|
osb->dc_work_sequence = osb->dc_wake_sequence;
|
|
osb->dc_work_sequence = osb->dc_wake_sequence;
|
|
|
|
|
|
processed = osb->blocked_lock_count;
|
|
processed = osb->blocked_lock_count;
|
|
- while (processed) {
|
|
|
|
- BUG_ON(list_empty(&osb->blocked_lock_list));
|
|
|
|
-
|
|
|
|
|
|
+ /*
|
|
|
|
+ * blocked lock processing in this loop might call iput which can
|
|
|
|
+ * remove items off osb->blocked_lock_list. Downconvert up to
|
|
|
|
+ * 'processed' number of locks, but stop short if we had some
|
|
|
|
+ * removed in ocfs2_mark_lockres_freeing when downconverting.
|
|
|
|
+ */
|
|
|
|
+ while (processed && !list_empty(&osb->blocked_lock_list)) {
|
|
lockres = list_entry(osb->blocked_lock_list.next,
|
|
lockres = list_entry(osb->blocked_lock_list.next,
|
|
struct ocfs2_lock_res, l_blocked_list);
|
|
struct ocfs2_lock_res, l_blocked_list);
|
|
list_del_init(&lockres->l_blocked_list);
|
|
list_del_init(&lockres->l_blocked_list);
|