aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/aops.c
diff options
context:
space:
mode:
authorJunxiao Bi <junxiao.bi@oracle.com>2014-12-18 19:17:37 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-18 22:08:11 -0500
commit136f49b9171074872f2a14ad0ab10486d1ba13ca (patch)
tree5ae9acaaa409866aae0308d6507e571756446b22 /fs/ocfs2/aops.c
parent1e5895816030eaadb952c89eb9f4054e5c0082c3 (diff)
ocfs2: fix journal commit deadlock
For buffer write, page lock will be got in write_begin and released in write_end, in ocfs2_write_end_nolock(), before it unlock the page in ocfs2_free_write_ctxt(), it calls ocfs2_run_deallocs(), this will ask for the read lock of journal->j_trans_barrier. Holding page lock and ask for journal->j_trans_barrier breaks the locking order. This will cause a deadlock with journal commit threads, ocfs2cmt will get write lock of journal->j_trans_barrier first, then it wakes up kjournald2 to do the commit work, at last it waits until done. To commit journal, kjournald2 needs flushing data first, it needs get the cache page lock. Since some ocfs2 cluster locks are holding by write process, this deadlock may hung the whole cluster. unlock pages before ocfs2_run_deallocs() can fix the locking order, also put unlock before ocfs2_commit_trans() to make page lock is unlocked before j_trans_barrier to preserve unlocking order. Signed-off-by: Junxiao Bi <junxiao.bi@oracle.com> Reviewed-by: Wengang Wang <wen.gang.wang@oracle.com> Cc: <stable@vger.kernel.org> Reviewed-by: Mark Fasheh <mfasheh@suse.de> Cc: Joel Becker <jlbec@evilplan.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
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}