|
@@ -894,7 +894,7 @@ void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
|
|
|
+static void ocfs2_unlock_pages(struct ocfs2_write_ctxt *wc)
|
|
|
{
|
|
|
int i;
|
|
|
|
|
@@ -915,7 +915,11 @@ static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
|
|
|
page_cache_release(wc->w_target_page);
|
|
|
}
|
|
|
ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages);
|
|
|
+}
|
|
|
|
|
|
+static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
|
|
|
+{
|
|
|
+ ocfs2_unlock_pages(wc);
|
|
|
brelse(wc->w_di_bh);
|
|
|
kfree(wc);
|
|
|
}
|
|
@@ -2042,11 +2046,19 @@ out_write_size:
|
|
|
ocfs2_update_inode_fsync_trans(handle, inode, 1);
|
|
|
ocfs2_journal_dirty(handle, wc->w_di_bh);
|
|
|
|
|
|
+ /* unlock pages before dealloc since it needs acquiring j_trans_barrier
|
|
|
+ * lock, or it will cause a deadlock since journal commit threads holds
|
|
|
+ * this lock and will ask for the page lock when flushing the data.
|
|
|
+ * put it here to preserve the unlock order.
|
|
|
+ */
|
|
|
+ ocfs2_unlock_pages(wc);
|
|
|
+
|
|
|
ocfs2_commit_trans(osb, handle);
|
|
|
|
|
|
ocfs2_run_deallocs(osb, &wc->w_dealloc);
|
|
|
|
|
|
- ocfs2_free_write_ctxt(wc);
|
|
|
+ brelse(wc->w_di_bh);
|
|
|
+ kfree(wc);
|
|
|
|
|
|
return copied;
|
|
|
}
|