aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/aops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r--fs/ocfs2/aops.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index d9f222987f24..46d93e941f3d 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -894,7 +894,7 @@ void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages)
894 } 894 }
895} 895}
896 896
897static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc) 897static void ocfs2_unlock_pages(struct ocfs2_write_ctxt *wc)
898{ 898{
899 int i; 899 int i;
900 900
@@ -915,7 +915,11 @@ static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
915 page_cache_release(wc->w_target_page); 915 page_cache_release(wc->w_target_page);
916 } 916 }
917 ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages); 917 ocfs2_unlock_and_free_pages(wc->w_pages, wc->w_num_pages);
918}
918 919
920static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc)
921{
922 ocfs2_unlock_pages(wc);
919 brelse(wc->w_di_bh); 923 brelse(wc->w_di_bh);
920 kfree(wc); 924 kfree(wc);
921} 925}
@@ -2042,11 +2046,19 @@ out_write_size:
2042 ocfs2_update_inode_fsync_trans(handle, inode, 1); 2046 ocfs2_update_inode_fsync_trans(handle, inode, 1);
2043 ocfs2_journal_dirty(handle, wc->w_di_bh); 2047 ocfs2_journal_dirty(handle, wc->w_di_bh);
2044 2048
2049 /* unlock pages before dealloc since it needs acquiring j_trans_barrier
2050 * lock, or it will cause a deadlock since journal commit threads holds
2051 * this lock and will ask for the page lock when flushing the data.
2052 * put it here to preserve the unlock order.
2053 */
2054 ocfs2_unlock_pages(wc);
2055
2045 ocfs2_commit_trans(osb, handle); 2056 ocfs2_commit_trans(osb, handle);
2046 2057
2047 ocfs2_run_deallocs(osb, &wc->w_dealloc); 2058 ocfs2_run_deallocs(osb, &wc->w_dealloc);
2048 2059
2049 ocfs2_free_write_ctxt(wc); 2060 brelse(wc->w_di_bh);
2061 kfree(wc);
2050 2062
2051 return copied; 2063 return copied;
2052} 2064}