diff options
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r-- | fs/ocfs2/aops.c | 16 |
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 | ||
897 | static void ocfs2_free_write_ctxt(struct ocfs2_write_ctxt *wc) | 897 | static 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 | ||
920 | static 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 | } |